Files
PVPlant/Export/exportDXF.py

696 lines
26 KiB
Python
Raw Normal View History

2025-01-28 00:04:13 +01:00
import math
import FreeCAD
from Utils.PVPlantUtils import findObjects
if FreeCAD.GuiUp:
import FreeCADGui
2025-03-28 19:39:33 +06:00
from PySide import QtCore, QtGui, QtWidgets
2025-01-28 00:04:13 +01:00
from PySide.QtCore import QT_TRANSLATE_NOOP
import os
else:
# \cond
def translate(ctxt, txt):
return txt
def QT_TRANSLATE_NOOP(ctxt, txt):
return txt
# \endcond
__title__ = "PVPlant Export to DXF"
__author__ = "Javier Braña"
__url__ = "http://www.sogos-solar.com"
import PVPlantResources
from PVPlantResources import DirIcons as DirIcons
field = {"name": "", "width": 0, "heigth": 0}
2025-03-28 19:39:33 +06:00
class LineTypeDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None):
super().__init__(parent)
self.line_types = [
{"name": "Continuous", "pen": QtCore.Qt.SolidLine},
{"name": "Dashed", "pen": QtCore.Qt.DashLine},
{"name": "Dotted", "pen": QtCore.Qt.DotLine},
{"name": "Dash-Dot", "pen": QtCore.Qt.DashDotLine},
{"name": "Dash-Dot-Dot", "pen": QtCore.Qt.DashDotDotLine}
]
def paint(self, painter, option, index):
# Dibujar el fondo
painter.save()
painter.setRenderHint(QtGui.QPainter.Antialiasing)
# Configuraciones comunes
line_color = QtGui.QColor(0, 0, 0) # Color de la línea
line_width = 2 # Grosor de línea
# Dibujar el ítem base
super().paint(painter, option, index)
# Obtener el tipo de línea
line_type = self.line_types[index.row()]
# Configurar el área de dibujo
text_rect = option.rect.adjusted(5, 0, -100, 0)
line_rect = option.rect.adjusted(option.rect.width() - 90, 2, -5, -2)
# Dibujar el texto
painter.drawText(text_rect, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, line_type["name"])
# Dibujar la línea de muestra
pen = QtGui.QPen(line_color, line_width, line_type["pen"])
painter.setPen(pen)
start_y = line_rect.center().y()
painter.drawLine(line_rect.left(), start_y, line_rect.right(), start_y)
painter.restore()
def sizeHint(self, option, index):
size = super().sizeHint(option, index)
size.setHeight(25) # Altura aumentada para mejor visualización
return size
class LineTypePreviewDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None):
super().__init__(parent)
'''self.line_types = [
("Continuous", QtCore.Qt.SolidLine),
("Dashed", QtCore.Qt.DashLine),
("Dotted", QtCore.Qt.DotLine),
("Dash-Dot", QtCore.Qt.DashDotLine),
("Dash-Dot-Dot", QtCore.Qt.DashDotDotLine)
]'''
self.line_types = [
{"name": "Continuous", "style": QtCore.Qt.SolidLine},
{"name": "Dashed", "style": QtCore.Qt.DashLine},
{"name": "Dotted", "style": QtCore.Qt.DotLine},
{"name": "Custom 1 (--0--0--)",
"style": QtCore.Qt.CustomDashLine,
"pattern": [8, 4, 2, 4]}, # Patrón personalizado
{"name": "Custom 2 (- - -)",
"style": QtCore.Qt.CustomDashLine,
"pattern": [6, 3]} # Otro patrón
]
def paint(self, painter, option, index):
painter.save()
painter.setRenderHint(QtGui.QPainter.Antialiasing)
if index.row() >= len(self.line_types):
painter.restore()
return
line_data = self.line_types[index.row()]
line_name = line_data["name"]
line_style = line_data.get("style", QtCore.Qt.SolidLine)
dash_pattern = line_data.get("pattern", [])
# Fondo para selección
if option.state & QtGui.QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.highlight())
# Áreas de dibujo
text_rect = option.rect.adjusted(5, 0, -100, 0)
preview_rect = option.rect.adjusted(option.rect.width() - 90, 2, -5, -2)
# Texto
painter.setPen(option.palette.color(QtGui.QPalette.Text))
painter.drawText(text_rect, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, line_name)
# Línea personalizada
pen = QtGui.QPen(QtGui.QColor(0, 0, 0), 2)
pen.setStyle(line_style)
if line_style == QtCore.Qt.CustomDashLine and dash_pattern:
pen.setDashPattern(dash_pattern)
painter.setPen(pen)
painter.drawLine(preview_rect.left(), preview_rect.center().y(),
preview_rect.right(), preview_rect.center().y())
painter.restore()
def sizeHint(self, option, index):
return QtCore.QSize(200, 25)
class LineTypeComboBox(QtWidgets.QComboBox):
def __init__(self, parent=None):
super().__init__(parent)
self._delegate = LineTypePreviewDelegate(self)
self.setItemDelegate(self._delegate)
self.addItems(["Continuous", "Dashed", "Dotted", "Dash-Dot", "Dash-Dot-Dot"])
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
# Dibujar el fondo del combobox
option = QtWidgets.QStyleOptionComboBox()
self.initStyleOption(option)
self.style().drawComplexControl(QtGui.QStyle.CC_ComboBox, option, painter, self)
# Obtener el texto y estilo actual
current_text = self.currentText()
line_style = next(
(style for name, style in self._delegate.line_types if name == current_text),
QtCore.Qt.SolidLine
)
# Área de dibujo
text_rect = self.rect().adjusted(5, 0, -30, 0)
preview_rect = self.rect().adjusted(self.width() - 70, 2, -5, -2)
# Dibujar texto
painter.setPen(self.palette().color(QtGui.QPalette.Text))
painter.drawText(text_rect, QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter, current_text)
# Dibujar línea de previsualización
pen = QtGui.QPen(QtGui.QColor(0, 0, 0), 2)
pen.setStyle(line_style)
painter.setPen(pen)
center_y = preview_rect.center().y()
painter.drawLine(preview_rect.left(), center_y, preview_rect.right(), center_y)
2025-01-28 00:04:13 +01:00
class exportDXF:
def __init__(self, filename):
''' '''
2025-03-28 19:39:33 +06:00
2025-01-28 00:04:13 +01:00
self.doc = None
self.msp = None
self.filename = filename
'''
doc.linetypes.add("GRENZE2",
# linetype definition in acad.lin:
# A,.25,-.1,[BOX,ltypeshp.shx,x=-.1,s=.1],-.1,1
# replacing BOX by shape index 132 (got index from an AutoCAD file),
# ezdxf can't get shape index from ltypeshp.shx
pattern="A,.25,-.1,[132,ltypeshp.shx,x=-.1,s=.1],-.1,1",
description="Grenze eckig ----[]-----[]----[]-----[]----[]--",
length=1.45, # required for complex line types
})
doc.linetypes.add("GRENZE2",
# linetype definition in acad.lin:
# A,.25,-.1,[BOX,ltypeshp.shx,x=-.1,s=.1],-.1,1
# replacing BOX by shape index 132 (got index from an AutoCAD file),
# ezdxf can't get shape index from ltypeshp.shx
pattern = "A,.25,-.1,[132,ltypeshp.shx,x=-.1,s=.1],-.1,1",
description = "Límite1 ----0-----0----0-----0----0-----0--",
length = 1.45, # required for complex line types
})
'''
def createFile(self, version='R2018'):
import ezdxf
from ezdxf.tools.standards import linetypes
# 1. Create a new document
self.doc = ezdxf.new(version)
# 2. Setup document:
self.doc.header["$INSUNITS"] = 6
self.doc.header['$MEASUREMENT'] = 1
self.doc.header['$LUNITS'] = 2
self.doc.header['$AUNITS'] = 0
# 3. Add new entities to the modelspace:
self.msp = self.doc.modelspace()
print("linetypes: ", self.doc.linetypes)
for name, desc, pattern in linetypes():
if name not in self.doc.linetypes:
self.doc.linetypes.add(name=name,
pattern=pattern,
description=desc,
)
self.doc.linetypes.add(name="FENCELINE1",
pattern="A,.25,-.1,[132,ltypeshp.shx,x=-.1,s=.1],-.1,1",
description="Límite1 ----0-----0----0-----0----0-----0--",
length=1.45) # required for complex line types
def save(self):
from os.path import exists
file_exists = exists(self.filename)
self.doc.saveas(self.filename)
self.doc.save()
def createLayer(self, layerName="newLayer", layerColor=(0,0,0), layerLineType='CONTINUOUS'):
layer = self.doc.layers.add(name=layerName, linetype=layerLineType)
layer.rgb = layerColor
return layer
def createBlock(self, blockName='newBlock'):
# Create a block
block = self.doc.blocks.new(name=blockName)
return block
def insertBlock(self, name, point=(0.0, 0.0), rotation=0.0, xscale=0.0, yscale=0.0):
if name == "":
return None
return self.msp.add_blockref(name, point, dxfattribs={
'xscale': xscale,
'yscale': yscale,
'rotation': rotation
})
def createPolyline(self, wire):
2025-06-15 23:10:17 +02:00
try:
data = getWire(wire.Shape)
lwp = self.msp.add_lwpolyline(data)
return lwp
except Exception as e:
print("Error creating polyline:", e)
return None
2025-01-28 00:04:13 +01:00
def getWire(wire, nospline=False, width=.0):
"""Return a list of DXF ready points and bulges from a wire.
It builds a list of points from the edges of a `wire`.
If the edges are circular arcs, the "bulge" of that edge is calculated,
for other cases, the bulge is considered zero.
Parameters
----------
wire : Part::TopoShape ('Wire')
A shape representing a wire.
nospline : bool, optional
It defaults to `False`.
If it is `True`, the edges of the wire are not considered as
being one of `'BSplineCurve'`, `'BezierCurve'`, or `'Ellipse'`,
and a simple point is added to the list.
Otherwise, `getSplineSegs(edge)` is used to extract
the points and add them to the list.
Returns
-------
list of tuples
It returns a list of tuples ``[(...), (...), ...]``
where each tuple indicates a point with additional information
besides the coordinates.
Two types of tuples may be returned.
[(float, float, float, None, None, float), ...]
When `lw` is `True` (`'lwpolyline'`)
the first three values represent the coordinates of the point,
the next two are `None`, and the last value is the bulge.
[((float, float, float), None, [None, None], float), ...]
When `lw` is `False` (`'polyline'`)
the first element is a tuple of three values that indicate
the coordinates of the point, the next element is `None`,
the next element is a list of two `None` values,
and the last element is the value of the bulge.
See also
--------
calcBulge
"""
import Part
import DraftGeomUtils
import math
def fmt(vec, b=0.0):
return (vec.x * 0.001, vec.y * 0.001, width, width, b)
points = []
edges = Part.__sortEdges__(wire.Edges)
for edge in edges:
v1 = edge.Vertexes[0].Point
if DraftGeomUtils.geomType(edge) == "Circle":
# polyline bulge -> negative makes the arc go clockwise
angle = edge.LastParameter - edge.FirstParameter
bul = math.tan(angle / 4)
if edge.Curve.Axis.dot(FreeCAD.Vector(0, 0, 1)) < 0:
bul = -bul
points.append(fmt(v1, bul))
elif (DraftGeomUtils.geomType(edge) in ["BSplineCurve",
"BezierCurve",
"Ellipse"]) and (not nospline):
spline = getSplineSegs(edge)
spline.pop()
for p in spline:
points.append(fmt(p))
else:
points.append(fmt(v1))
v = edges[-1].Vertexes[-1].Point
points.append(fmt(v))
return points
def getArcData(edge):
"""Return center, radius, start, and end angles of a circle-based edge.
Parameters
----------
edge : Part::TopoShape ('Edge')
An edge representing a circular arc, either open or closed.
Returns
-------
(tuple, float, float, float)
It returns a tuple of four values; the first value is a tuple
with the coordinates of the center `(x, y, z)`;
the other three represent the magnitude of the radius,
and the start and end angles in degrees that define the arc.
(tuple, float, 0, 0)
If the number of vertices in the `edge` is only one, only the center
point exists, so it's a full circumference; in this case, both
angles are zero.
"""
ce = edge.Curve.Center
radius = edge.Curve.Radius
if len(edge.Vertexes) == 1:
# closed circle
return DraftVecUtils.tup(ce), radius, 0, 0
else:
# new method: recalculate ourselves as we cannot trust edge.Curve.Axis
# or XAxis
p1 = edge.Vertexes[0].Point
p2 = edge.Vertexes[-1].Point
v1 = p1.sub(ce)
v2 = p2.sub(ce)
# print(v1.cross(v2))
# print(edge.Curve.Axis)
# print(p1)
# print(p2)
# we can use Z check since arcs getting here will ALWAYS be in XY plane
# Z can be 0 if the arc is 180 deg
# if (v1.cross(v2).z >= 0) or (edge.Curve.Axis.z > 0):
# Calculates the angles of the first and last points
# in the circular arc, with respect to the global X axis.
if edge.Curve.Axis.z > 0:
# clockwise
ang1 = -DraftVecUtils.angle(v1)
ang2 = -DraftVecUtils.angle(v2)
else:
# counterclockwise
ang2 = -DraftVecUtils.angle(v1)
ang1 = -DraftVecUtils.angle(v2)
# obsolete method - fails a lot
# if round(edge.Curve.Axis.dot(Vector(0, 0, 1))) == 1:
# ang1, ang2 = edge.ParameterRange
# else:
# ang2, ang1 = edge.ParameterRange
# if edge.Curve.XAxis != Vector(1, 0, 0):
# ang1 -= DraftVecUtils.angle(edge.Curve.XAxis)
# ang2 -= DraftVecUtils.angle(edge.Curve.XAxis)
return (DraftVecUtils.tup(ce), radius,
math.degrees(ang1), math.degrees(ang2))
class _PVPlantExportDXF(QtGui.QWidget):
'''The editmode TaskPanel to select what you want to export'''
def __init__(self):
# super(_PVPlantExportDXF, self).__init__()
QtGui.QWidget.__init__(self)
import os
2025-03-28 19:39:33 +06:00
from datetime import datetime
2025-01-28 00:04:13 +01:00
# self.form:
self.form = FreeCADGui.PySideUic.loadUi(
os.path.join(os.path.dirname(os.path.realpath(__file__)), "exportDXF.ui"))
# setWindowIcon(QtGui.QIcon(os.path.join(PVPlantResources.DirIcons, "convert.svg")))
# self.form.buttonTo.clicked.connect(self.addTo)
2025-03-28 19:39:33 +06:00
self.form.tableLayers.setItemDelegateForColumn(3, LineTypeDelegate())
2025-01-28 00:04:13 +01:00
self.layout = QtGui.QHBoxLayout(self)
self.layout.setContentsMargins(4, 4, 4, 4)
self.layout.addWidget(self.form)
self.form.buttonAcept.clicked.connect(self.onAceptClick)
2025-03-28 19:39:33 +06:00
self.add_row("Layer 1", QtGui.QColor(255, 0, 0), "Continua", "1")
self.add_row("Layer 2", QtGui.QColor(255, 0, 0), "Continua", "1")
2025-01-28 00:04:13 +01:00
path = os.path.join(os.path.dirname(FreeCAD.ActiveDocument.FileName), "outputs", "autocad")
if not os.path.exists(path):
os.makedirs(path)
2025-03-28 19:39:33 +06:00
name = datetime.now().strftime("%Y%m%d%H%M%S") + "-" + FreeCAD.ActiveDocument.Name
self.filename = os.path.join(path, name) + ".dxf"
def add_row(self, name, color, line_type, thickness):
row = self.form.tableLayers.rowCount()
self.form.tableLayers.insertRow(row)
self.form.tableLayers.setRowHeight(row, 20)
# Columna 0: Checkbox
checkbox = QtWidgets.QCheckBox()
cell_widget = QtWidgets.QWidget()
layout = QtWidgets.QHBoxLayout(cell_widget)
layout.addWidget(checkbox)
layout.setAlignment(QtCore.Qt.AlignCenter)
layout.setContentsMargins(0, 0, 0, 0)
self.form.tableLayers.setCellWidget(row, 0, cell_widget)
# Columna 1: Nombre (editable)
item = QtWidgets.QTableWidgetItem(name)
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
self.form.tableLayers.setItem(row, 1, item)
# Columna 2: Selector de color
color_btn = QtWidgets.QPushButton()
color_btn.setFixedSize(20, 20) # Tamaño del cuadrado
color_btn.setStyleSheet(f"""
QPushButton {{
background-color: {color.name()};
border: 1px solid #808080;
border-radius: 3px;
}}
QPushButton:hover {{
border: 2px solid #606060;
}}
""")
color_btn.color = color # Almacenar el color como atributo
color_btn.clicked.connect(lambda: self.change_color(color_btn))
# Widget contenedor para centrar el botón
cell_widget = QtWidgets.QWidget()
layout = QtWidgets.QHBoxLayout(cell_widget)
layout.addWidget(color_btn)
layout.setAlignment(QtCore.Qt.AlignCenter)
layout.setContentsMargins(0, 0, 0, 0)
self.form.tableLayers.setCellWidget(row, 2, cell_widget)
# Columna 3: Tipo de línea (combobox)
line_combo = LineTypeComboBox()
line_combo.addItems(["Continua", "Discontinua", "Punteada", "Mixta"])
line_combo.setCurrentText(line_type)
self.form.tableLayers.setCellWidget(row, 3, line_combo)
# Columna 4: Grosor de línea (combobox)
thickness_combo = QtWidgets.QComboBox()
thickness_combo.addItems(["1", "2", "3", "4"])
thickness_combo.setCurrentText(thickness)
self.form.tableLayers.setCellWidget(row, 4, thickness_combo)
def change_color(self, button):
color = QtWidgets.QColorDialog.getColor(button.color, self, "Seleccionar color")
if color.isValid():
button.color = color
button.setStyleSheet(f"background-color: {color.name()}")
2025-01-28 00:04:13 +01:00
def createLayers(self):
''' '''
self.exporter.createLayer("Areas_Boundary", layerColor=(0, 125, 125), layerLineType="FENCELINE1")
self.exporter.createLayer("Areas_Exclusion", layerColor=(255, 0, 0))
self.exporter.createLayer("Areas_Offsets", layerColor=(128, 128, 255))
self.exporter.createLayer("Internal_Roads", layerColor=(128, 128, 128))
self.exporter.createLayer("Internal_Roads_Axis", layerColor=(255, 255, 255), layerLineType="DASHEDX2")
def writeArea(self):
2025-03-28 19:39:33 +06:00
pol = self.exporter.createPolyline(FreeCAD.ActiveDocument.Site.Boundary)
2025-06-15 23:10:17 +02:00
if pol:
pol.dxf.layer = "boundary"
2025-03-28 19:39:33 +06:00
for area in FreeCAD.ActiveDocument.Boundaries.Group:
2025-01-28 00:04:13 +01:00
pol = self.exporter.createPolyline(area)
pol.dxf.layer = "Areas_Boundary"
2025-03-28 19:39:33 +06:00
for area in FreeCAD.ActiveDocument.Exclusions.Group:
2025-01-28 00:04:13 +01:00
pol = self.exporter.createPolyline(area)
pol.dxf.layer = "Areas_Exclusion"
for area in FreeCAD.ActiveDocument.Offsets.Group:
2025-03-28 19:39:33 +06:00
pol = self.exporter.createPolyline(area)
2025-01-28 00:04:13 +01:00
pol.dxf.layer = "Areas_Offsets"
def writeFrameSetups(self):
import Part
# 1. Profiles:
profilelist = list()
for ts in FreeCAD.ActiveDocument.Site.Frames:
for poletype in ts.PoleType:
if not (poletype in profilelist):
profilelist.append(poletype)
block = self.exporter.createBlock(poletype.Label)
w = poletype.Base.Shape.Wires[0]
w.Placement.Base = FreeCAD.Vector(w.Placement.Base).sub(w.BoundBox.Center)
block.add_lwpolyline(getWire(w))
block.add_circle((0, 0), 0.2, dxfattribs={'color': 2})
p = math.sin(math.radians(45)) * 0.2
block.add_line((-p, -p), (p, p), dxfattribs={"layer": "MyLines"})
block.add_line((-p, p), (p, -p), dxfattribs={"layer": "MyLines"})
# 2. Frames
for ts in FreeCAD.ActiveDocument.Site.Frames:
w = max(ts.Shape.SubShapes[0].SubShapes[0].SubShapes[0].Faces, key=lambda x: x.Area)
pts = [w.BoundBox.getPoint(i) for i in range(4)]
pts.append(FreeCAD.Vector(pts[0]))
w = Part.makePolygon(pts)
w.Placement.Base = w.Placement.Base.sub(w.BoundBox.Center)
mblockname = "Trina_TSM-DEG21C-20-6XXWp Vertex"
mblock = self.exporter.createBlock(mblockname)
mblock.add_lwpolyline(getWire(w))
rblock = self.exporter.createBlock(ts.Label)
w = max(ts.Shape.SubShapes[0].SubShapes[1].SubShapes[0].Faces, key=lambda x: x.Placement.Base.z).Wires[0]
w.Placement.Base = w.Placement.Base.sub(w.BoundBox.Center)
rblock.add_lwpolyline(getWire(w))
for module in ts.Shape.SubShapes[0].SubShapes[0].SubShapes:
point = FreeCAD.Vector(module.BoundBox.Center) * 0.001
point = point[:2]
rblock.add_blockref(mblockname, point, dxfattribs={
'xscale': .0,
'yscale': .0,
'rotation': 0})
for ind in range(int(ts.NumberPole.Value)):
point = ts.Shape.SubShapes[1].SubShapes[0].SubShapes[ind].Placement.Base * 0.001
point = point[:2]
name = ts.PoleType[ts.PoleSequence[ind]].Label
rblock.add_blockref(name, point, dxfattribs={
'xscale': .0,
'yscale': .0,
'rotation': 0})
def writeFrames(self):
objects = findObjects('Tracker')
for frame in objects:
if hasattr(frame, "Setup"):
point = frame.Placement.Base * 0.001
point = point[:2]
self.exporter.insertBlock(frame.Setup.Label, point=point, rotation=frame.AngleZ)
def writeRoads(self):
objects = findObjects("Road")
#rblock = self.exporter.createBlock("Internal_roads")
for road in objects:
base = self.exporter.createPolyline(road.Base)
base.dxf.const_width = road.Width.Value * 0.001
base.dxf.layer = "Internal_Roads"
axis = self.exporter.createPolyline(road.Base)
axis.dxf.const_width = .2
axis.dxf.layer = "Internal_Roads_Axis"
#my_lines = doc.layers.get('MyLines')
def writeTrenches(self):
objects = findObjects("Trench")
# rblock = self.exporter.createBlock("Internal_roads")
for obj in objects:
base = self.exporter.createPolyline(obj.Base)
base.dxf.const_width = obj.Width.Value * 0.001
base.dxf.layer = "Trench"
def setup_layout4(self, doc):
layout2 = doc.layouts.new("scale 1-1")
# The default paperspace scale is 1:1
# 1 mm printed is 1 drawing unit in paperspace
# For most use cases this is the preferred scaling and important fact:
# the paperspace scaling has no influence on the VIEWPORT scaling - this is
# a total different topic, see example "viewports_in_paperspace.py"
layout2.page_setup(size=(297, 210),
margins=(10, 10, 10, 10),
units="mm",
scale=(1, 1),
#offset=(50, 50),
)
layout2.add_viewport(
# center of viewport in paperspace units
center=(100, 100),
# viewport size in paperspace units
size=(50, 50),
# modelspace point to show in center of viewport in WCS
view_center_point=(60, 40),
# how much modelspace area to show in viewport in drawing units
view_height=20,
#status=2,
)
lower_left, upper_right = layout2.get_paper_limits()
x1, y1 = lower_left
x2, y2 = upper_right
center = lower_left.lerp(upper_right)
# Add DXF entities to the "Layout1" in paperspace coordinates:
layout2.add_line((x1, center.y), (x2, center.y)) # horizontal center line
layout2.add_line((center.x, y1), (center.x, y2)) # vertical center line
layout2.add_circle((0, 0), radius=5) # plot origin
def onAceptClick(self):
self.exporter = exportDXF(self.filename)
if self.exporter:
self.exporter.createFile()
self.createLayers()
self.writeArea()
self.writeFrameSetups()
self.writeFrames()
self.writeRoads()
self.writeTrenches()
self.setup_layout4(self.exporter.doc)
self.exporter.save()
print(self.filename)
self.close()
2025-03-28 19:39:33 +06:00
class CommandExportDXF:
2025-01-28 00:04:13 +01:00
def GetResources(self):
return {'Pixmap': str(os.path.join(DirIcons, "dxf.svg")),
'Accel': "E, A",
'MenuText': "Export to DXF",
'ToolTip': QT_TRANSLATE_NOOP("Placement", "Export choosed layers to dxf")}
def Activated(self):
taskd = _PVPlantExportDXF()
taskd.setParent(FreeCADGui.getMainWindow())
taskd.setWindowFlags(QtCore.Qt.Dialog or QtCore.Qt.Dialog)
taskd.setWindowModality(QtCore.Qt.WindowModal)
taskd.show()
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
2025-03-28 19:39:33 +06:00
'''if FreeCAD.GuiUp:
FreeCADGui.addCommand('exportDXF', _CommandExportDXF())'''