Import: DXF importer, refactor preferences UI

This commit is contained in:
Furgo
2025-06-26 12:09:26 +02:00
parent 519daa0b38
commit 37cd1a657a
4 changed files with 614 additions and 523 deletions

View File

@@ -6,27 +6,28 @@
<rect>
<x>0</x>
<y>0</y>
<width>649</width>
<height>800</height>
<width>600</width>
<height>880</height>
</rect>
</property>
<property name="windowTitle">
<string>DXF</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<layout class="QVBoxLayout" name="verticalLayout_Main">
<item>
<widget class="QGroupBox" name="groupBox">
<widget class="QGroupBox" name="groupBox_General">
<property name="title">
<string>General options</string>
<string>General</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_General">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfShowDialog">
<property name="toolTip">
<string>This preferences dialog will be shown when importing/ exporting DXF files</string>
<string>If checked, this preferences dialog will be shown each time you import or export
a DXF file.</string>
</property>
<property name="text">
<string>Show this dialog when importing and exporting</string>
<string>Show the importer dialog when importing a file</string>
</property>
<property name="checked">
<bool>true</bool>
@@ -42,14 +43,10 @@
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfUseLegacyImporter">
<property name="toolTip">
<string>Python importer is used, otherwise the newer C++ is used.
Note: C++ importer is faster, but is not as featureful yet</string>
<string>Use the legacy Python importer. This importer is more feature-complete but slower and requires an external library.</string>
</property>
<property name="text">
<string>Use legacy Python importer</string>
</property>
<property name="checked">
<bool>false</bool>
<string>Use legacy importer</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfUseLegacyImporter</cstring>
@@ -62,11 +59,10 @@ Note: C++ importer is faster, but is not as featureful yet</string>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfUseLegacyExporter">
<property name="toolTip">
<string>Python exporter is used, otherwise the newer C++ is used.
Note: C++ exporter is faster, but is not as featureful yet</string>
<string>Use the legacy Python exporter. This exporter is more feature-complete but slower and requires an external library.</string>
</property>
<property name="text">
<string>Use legacy Python exporter</string>
<string>Use legacy exporter</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfUseLegacyExporter</cstring>
@@ -80,227 +76,160 @@ Note: C++ exporter is faster, but is not as featureful yet</string>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_1">
<widget class="QGroupBox" name="groupBox_AutoUpdate">
<property name="title">
<string>Automatic update (legacy importer/exporter only)</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_1">
<layout class="QVBoxLayout" name="verticalLayout_AutoUpdate">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_1">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfAllowDownload">
<property name="toolTip">
<string>Allow FreeCAD to download the Python converter for DXF import and export.
You can also do this manually by installing the &quot;dxf_library&quot; workbench
from the Addon Manager.</string>
</property>
<property name="text">
<string>Allow FreeCAD to automatically download and update the DXF libraries</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfAllowDownload</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfAllowDownload">
<property name="toolTip">
<string>If checked, FreeCAD is allowed to download and update the Python libraries
required by the legacy importer. This can also be done manually by installing
the 'dxf_library' addon from the Addon Manager.</string>
</property>
<property name="text">
<string>Allow FreeCAD to automatically download and update the DXF libraries</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfAllowDownload</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="GroupBox_2">
<widget class="QGroupBox" name="groupBox_ImportAs">
<property name="title">
<string>Import options</string>
<string>Import as</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_ImportAs">
<item>
<widget class="QLabel" name="label_ImporterMissing">
<property name="font">
<font>
<italic>true</italic>
</font>
<widget class="Gui::PrefRadioButton" name="radio_ImportAs_Draft">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Creates fully parametric Draft objects. Block definitions are imported as
reusable objects (Part Compounds) and instances become `App::Link` objects,
maintaining the block structure. Best for full integration with the Draft
Workbench. (Legacy importer only)</string>
</property>
<property name="text">
<string>Some options are not yet available for the new importer</string>
<string>Editable draft objects (Highest fidelity, slowest)</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>DxfImportMode</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
<property name="prefRadioButtonGroup" stdset="0">
<string>DxfImportMode</string>
</property>
<property name="prefRadioButtonValue" stdset="0">
<number>0</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_Import">
<property name="text">
<string>Import</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxftext">
<property name="toolTip">
<string>If unchecked, texts and mtexts won't be imported</string>
</property>
<property name="text">
<string>Texts and dimensions</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxftext</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfImportPoints">
<property name="toolTip">
<string>If unchecked, points won't be imported</string>
</property>
<property name="text">
<string>points</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfImportPoints</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxflayout">
<property name="toolTip">
<string>If checked, paper space objects will be imported too</string>
</property>
<property name="text">
<string>Layouts</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxflayout</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfstarblocks">
<property name="toolTip">
<string>If you want the non-named blocks (beginning with a *) to be imported too</string>
</property>
<property name="text">
<string>*blocks</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfstarblocks</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
<widget class="Gui::PrefRadioButton" name="radio_ImportAs_Primitives">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Creates parametric Part objects (e.g., Part::Line, Part::Circle). Block
definitions are imported as reusable objects (Part Compounds) and instances
become `App::Link` objects, maintaining the block structure. Best for
script-based post-processing. (Not yet implemented)</string>
</property>
<property name="text">
<string>Editable part primitives (High fidelity, slower)</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>DxfImportMode</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
<property name="prefRadioButtonGroup" stdset="0">
<string>DxfImportMode</string>
</property>
<property name="prefRadioButtonValue" stdset="0">
<number>1</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_Create">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Create</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefRadioButton" name="radioButton_dxfCreatePart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Only standard Part objects will be created (fastest)</string>
</property>
<property name="text">
<string>Simple Part shapes</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfCreatePart</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefRadioButton" name="radioButton_dxfCreateDraft">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Parametric Draft objects will be created whenever possible</string>
</property>
<property name="text">
<string>Draft objects</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfCreateDraft</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefRadioButton" name="radioButton_dxfCreateSketch">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Sketches will be created whenever possible</string>
</property>
<property name="text">
<string>Sketches</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfCreateSketch</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
<widget class="Gui::PrefRadioButton" name="radio_ImportAs_Shapes">
<property name="toolTip">
<string>Creates a non-parametric shape for each DXF entity. Block definitions are
imported as reusable objects (Part Compounds) and instances become `App::Link`
objects, maintaining the block structure. Good for referencing and measuring.</string>
</property>
<property name="text">
<string>Individual part shapes (Balanced, recommended)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>DxfImportMode</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
<property name="prefRadioButtonGroup" stdset="0">
<string>DxfImportMode</string>
</property>
<property name="prefRadioButtonValue" stdset="0">
<number>2</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<widget class="Gui::PrefRadioButton" name="radio_ImportAs_Fused">
<property name="toolTip">
<string>Merges all geometry per layer into a single, non-editable shape. Block
structures are not preserved; their geometry becomes part of the layer's
shape. Best for viewing very large files with maximum performance.</string>
</property>
<property name="text">
<string>Fused part shapes (Lowest fidelity, fastest)</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>DxfImportMode</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
<property name="prefRadioButtonGroup" stdset="0">
<string>DxfImportMode</string>
</property>
<property name="prefRadioButtonValue" stdset="0">
<number>3</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_ImportSettings">
<property name="title">
<string>Import settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_ImportSettings">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_Scaling">
<item>
<widget class="QLabel" name="label_dxfScaling">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Scale factor to apply to imported files</string>
<string>Global scaling factor:</string>
</property>
</widget>
</item>
@@ -320,13 +249,13 @@ from the Addon Manager.</string>
<item>
<widget class="Gui::PrefDoubleSpinBox" name="spinBox_dxfScaling">
<property name="toolTip">
<string>Scale factor to apply to DXF files on import.
The factor is the conversion between the unit of your DXF file and millimeters.
Example: for files in millimeters: 1, in centimeters: 10,
in meters: 1000, in inches: 25.4, in feet: 304.8</string>
<string>Scale factor to apply to DXF files on import. The factor is the conversion
between the unit of your DXF file and millimeters. Example: for files in
millimeters: 1, in centimeters: 10, in meters: 1000, in inches: 25.4,
in feet: 304.8</string>
</property>
<property name="decimals">
<number>12</number>
<number>6</number>
</property>
<property name="maximum">
<double>999999.999998999992386</double>
@@ -345,16 +274,126 @@ Example: for files in millimeters: 1, in centimeters: 10,
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_ImportContent">
<property name="text">
<string>Import:</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_Import">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="checkBox_dxftext">
<property name="toolTip">
<string>If checked, text, mtext, and dimension entities will be imported as Draft objects.</string>
</property>
<property name="text">
<string>Texts and dimensions</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxftext</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::PrefCheckBox" name="checkBox_dxfImportPoints">
<property name="toolTip">
<string>If checked, point entities will be imported.</string>
</property>
<property name="text">
<string>Points</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfImportPoints</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::PrefCheckBox" name="checkBox_dxflayout">
<property name="toolTip">
<string>If checked, entities from the paper space will also be imported. By default,
only model space is imported.</string>
</property>
<property name="text">
<string>Paper space objects</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxflayout</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::PrefCheckBox" name="checkBox_dxfstarblocks">
<property name="toolTip">
<string>If checked, anonymous blocks (whose names begin with *) will also be imported.
These are often used for hatches and dimensions.</string>
</property>
<property name="text">
<string>Anonymous blocks (*-blocks)</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfstarblocks</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="Gui::PrefCheckBox" name="checkBox_importDxfHatches">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>If checked, the boundaries of hatch objects will be imported as closed wires.
(Legacy importer only)</string>
</property>
<property name="text">
<string>Hatch boundaries</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>importDxfHatches</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_Appearance">
<property name="text">
<string>Appearance:</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_Appearance">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="checkBox_dxfGetOriginalColors">
<property name="toolTip">
<string>Colors will set as specified in the DXF file whenever possible.
Otherwise default colors will be applied.</string>
<string>If checked, colors will be set as specified in the DXF file whenever
possible. Otherwise, default FreeCAD colors are applied.</string>
</property>
<property name="text">
<string>Use colors from the DXF file</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfGetOriginalColors</cstring>
</property>
@@ -363,63 +402,14 @@ Otherwise default colors will be applied.</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_joingeometry">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>FreeCAD will try to join coincident objects into wires.
Note that this can take a while!</string>
</property>
<property name="text">
<string>Join geometry</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>joingeometry</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_groupLayers">
<property name="toolTip">
<string>Objects from the same layers will be joined into Part Compounds,
turning the display faster, but making them less easily editable.</string>
</property>
<property name="text">
<string>Merge layer contents into blocks</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>groupLayers</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<item row="0" column="1">
<widget class="Gui::PrefCheckBox" name="checkBox_dxfStdSize">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Imported texts will get the standard Draft Text size,
instead of the size they have in the DXF document</string>
<string>If checked, imported texts will get the standard Draft Text size, instead of
the size defined in the DXF document. (Legacy importer only)</string>
</property>
<property name="text">
<string>Use standard font size for texts</string>
@@ -435,61 +425,42 @@ instead of the size they have in the DXF document</string>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfUseDraftVisGroups">
<property name="toolTip">
<string>If this is checked, DXF layers will be imported as Draft Layers</string>
</property>
<property name="text">
<string>Use layers</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfUseDraftVisGroups</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
<widget class="QLabel" name="label_AdvancedProcessing">
<property name="text">
<string>Advanced processing:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_importDxfHatches">
<layout class="QGridLayout" name="gridLayout_Advanced">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="checkBox_joingeometry">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Hatches will be converted into simple wires</string>
<string>If checked, the legacy importer will attempt to join coincident geometric
objects into wires. This can be slow for large files. (Legacy importer only)</string>
</property>
<property name="text">
<string>Import hatch boundaries as wires</string>
<string>Join geometry</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>importDxfHatches</cstring>
<cstring>joingeometry</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<item row="0" column="1">
<widget class="Gui::PrefCheckBox" name="checkBox_renderPolylineWidth">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>If polylines have a width defined, they will be rendered
as closed wires with correct width</string>
<string>If checked, polylines that have a width property will be rendered as faces
representing that width. (Legacy importer only)</string>
</property>
<property name="text">
<string>Render polylines with width</string>
@@ -502,31 +473,39 @@ as closed wires with correct width</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::PrefCheckBox" name="checkBox_dxfCreateSketch">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>If checked, the legacy importer will attempt to create Sketcher objects
instead of Draft or Part objects. This overrides the 'Import as' setting.</string>
</property>
<property name="text">
<string>Create sketches (legacy importer only)</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>dxfCreateSketch</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Draft</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<widget class="QGroupBox" name="groupBox_ExportOptions">
<property name="title">
<string>Export options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout_Export">
<item>
<widget class="QLabel" name="label_ExporterMissing">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Some options are not yet available for the new exporter</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<layout class="QHBoxLayout" name="horizontalLayout_Discretize">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_DiscretizeEllipses">
<property name="toolTip">
@@ -598,7 +577,7 @@ If it is set to '0' the whole spline is treated as a straight segment.</string>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<layout class="QHBoxLayout" name="horizontalLayout_Export3D">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfmesh">
<property name="enabled">
@@ -621,7 +600,7 @@ If it is set to '0' the whole spline is treated as a straight segment.</string>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<layout class="QHBoxLayout" name="horizontalLayout_ExportTechDraw">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfExportBlocks">
<property name="toolTip">
@@ -645,7 +624,7 @@ This might fail for post DXF R12 templates.</string>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_15">
<layout class="QHBoxLayout" name="horizontalLayout_Project">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_dxfproject">
<property name="enabled">
@@ -671,21 +650,20 @@ This might fail for post DXF R12 templates.</string>
</widget>
</item>
<item>
<spacer name="verticalSpacer_1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>Gui::PrefCheckBox</class>
@@ -693,82 +671,18 @@ This might fail for post DXF R12 templates.</string>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<class>Gui::PrefRadioButton</class>
<extends>QRadioButton</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefRadioButton</class>
<extends>QRadioButton</extends>
<class>Gui::PrefDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>checkBox_dxfUseLegacyImporter</sender>
<signal>toggled(bool)</signal>
<receiver>label_Create</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfUseLegacyImporter</sender>
<signal>toggled(bool)</signal>
<receiver>radioButton_dxfCreatePart</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfUseLegacyImporter</sender>
<signal>toggled(bool)</signal>
<receiver>radioButton_dxfCreateDraft</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfUseLegacyImporter</sender>
<signal>toggled(bool)</signal>
<receiver>radioButton_dxfCreateSketch</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfUseLegacyImporter</sender>
<signal>toggled(bool)</signal>
@@ -785,6 +699,22 @@ This might fail for post DXF R12 templates.</string>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfUseLegacyImporter</sender>
<signal>toggled(bool)</signal>
<receiver>checkBox_renderPolylineWidth</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfUseLegacyImporter</sender>
<signal>toggled(bool)</signal>
@@ -820,7 +750,55 @@ This might fail for post DXF R12 templates.</string>
<connection>
<sender>checkBox_dxfUseLegacyImporter</sender>
<signal>toggled(bool)</signal>
<receiver>checkBox_renderPolylineWidth</receiver>
<receiver>checkBox_dxfCreateSketch</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfCreateSketch</sender>
<signal>toggled(bool)</signal>
<receiver>groupBox_ImportAs</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfUseLegacyExporter</sender>
<signal>toggled(bool)</signal>
<receiver>checkBox_dxfmesh</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkBox_dxfUseLegacyExporter</sender>
<signal>toggled(bool)</signal>
<receiver>checkBox_dxfproject</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">

View File

@@ -4163,6 +4163,8 @@ def getViewDXF(view):
return block, insert
# In src/Mod/Draft/importDXF.py
def readPreferences():
"""Read the preferences of the this module from the parameter database.
@@ -4184,6 +4186,7 @@ def readPreferences():
# reading parameters
if gui and params.get_param("dxfShowDialog"):
FreeCADGui.showPreferencesByName("Import-Export", ":/ui/preferences-dxf.ui")
global dxfCreatePart, dxfCreateDraft, dxfCreateSketch
global dxfDiscretizeCurves, dxfStarBlocks
global dxfMakeBlocks, dxfJoin, dxfRenderPolylineWidth
@@ -4193,28 +4196,66 @@ def readPreferences():
global dxfMakeFaceMode, dxfBrightBackground, dxfDefaultColor
global dxfUseLegacyImporter, dxfExportBlocks, dxfScaling
global dxfUseLegacyExporter
dxfCreatePart = params.get_param("dxfCreatePart")
dxfCreateDraft = params.get_param("dxfCreateDraft")
dxfCreateSketch = params.get_param("dxfCreateSketch")
dxfDiscretizeCurves = params.get_param("DiscretizeEllipses")
dxfStarBlocks = params.get_param("dxfstarblocks")
dxfMakeBlocks = params.get_param("groupLayers")
dxfJoin = params.get_param("joingeometry")
dxfRenderPolylineWidth = params.get_param("renderPolylineWidth")
dxfImportTexts = params.get_param("dxftext")
dxfImportLayouts = params.get_param("dxflayout")
dxfImportPoints = params.get_param("dxfImportPoints")
dxfImportHatches = params.get_param("importDxfHatches")
dxfUseStandardSize = params.get_param("dxfStdSize")
dxfGetColors = params.get_param("dxfGetOriginalColors")
dxfUseDraftVisGroups = params.get_param("dxfUseDraftVisGroups")
dxfMakeFaceMode = params.get_param("MakeFaceMode")
dxfUseLegacyImporter = params.get_param("dxfUseLegacyImporter")
dxfUseLegacyExporter = params.get_param("dxfUseLegacyExporter")
# --- Read all feature and appearance toggles ---
# These are independent settings and can be read directly.
dxfDiscretizeCurves = params.get_param("DiscretizeEllipses", False)
dxfStarBlocks = params.get_param("dxfstarblocks", False)
dxfJoin = params.get_param("joingeometry", False)
dxfRenderPolylineWidth = params.get_param("renderPolylineWidth", False)
dxfImportTexts = params.get_param("dxftext", True)
dxfImportLayouts = params.get_param("dxflayout", False)
dxfImportPoints = params.get_param("dxfImportPoints", True)
dxfImportHatches = params.get_param("importDxfHatches", True)
dxfUseStandardSize = params.get_param("dxfStdSize", False)
dxfGetColors = params.get_param("dxfGetOriginalColors", True)
dxfUseDraftVisGroups = params.get_param("dxfUseDraftVisGroups", True)
dxfMakeFaceMode = params.get_param("MakeFaceMode", False)
dxfExportBlocks = params.get_param("dxfExportBlocks", True)
dxfScaling = params.get_param("dxfScaling", 1.0)
# These control which importer is used. The script should only proceed if
# the legacy importer is selected.
dxfUseLegacyImporter = params.get_param("dxfUseLegacyImporter", False)
dxfUseLegacyExporter = params.get_param("dxfUseLegacyExporter", False)
if not dxfUseLegacyImporter:
# If the legacy importer is called when not selected, exit.
# This prevents accidental execution.
return
# --- New, Centralized Logic for Structural Mode ---
# Read the legacy-specific override for sketch creation.
dxfCreateSketch = params.get_param("dxfCreateSketch", False)
if dxfCreateSketch:
# Sketch mode takes highest priority, other modes are irrelevant.
dxfCreatePart = False
dxfCreateDraft = False
dxfMakeBlocks = False
else:
# Not in sketch mode, so determine structure from DxfImportMode.
# This is where the new parameter is read, with its default value defined.
# 0=Draft, 1=Primitives, 2=Shapes, 3=Fused
import_mode = params.get_param("DxfImportMode", 2) # Default to "Individual part shapes"
if import_mode == 3: # Fused part shapes
dxfMakeBlocks = True # 'groupLayers' is the legacy equivalent
dxfCreatePart = False # In legacy, dxfMakeBlocks overrides these
dxfCreateDraft = False
elif import_mode == 0: # Editable draft objects
dxfMakeBlocks = False
dxfCreatePart = False
dxfCreateDraft = True
else: # Covers modes 1 (Primitives) and 2 (Shapes). Legacy maps both to "Simple part shapes"
dxfMakeBlocks = False
dxfCreatePart = True
dxfCreateDraft = False
# --- Other settings that are not checkboxes ---
dxfBrightBackground = isBrightBackground()
dxfDefaultColor = getColor()
dxfExportBlocks = params.get_param("dxfExportBlocks")
dxfScaling = params.get_param("dxfScaling")
class DxfImportReporter:

View File

@@ -106,12 +106,23 @@ void ImpExpDxfRead::StartImport()
bool ImpExpDxfRead::ReadEntitiesSection()
{
// TODO: remove this once the unsupported modes have been implemented.
// Perform a one-time check for unsupported modes
if (m_importMode == ImportMode::EditableDraft) {
UnsupportedFeature("Import as 'Editable draft objects' is not yet implemented.");
// We can continue, and the switch statements below will do nothing,
// resulting in an empty import for geometry, which is correct behavior.
}
else if (m_importMode == ImportMode::EditablePrimitives) {
UnsupportedFeature("Import as 'Editable part primitives' is not yet implemented.");
}
// After parsing the BLOCKS section, compose all block definitions
// into FreeCAD objects before processing the ENTITIES section.
ComposeBlocks();
DrawingEntityCollector collector(*this);
if (m_mergeOption < SingleShapes) {
if (m_importMode == ImportMode::FusedShapes) {
std::map<CDxfRead::CommonEntityAttributes, std::list<TopoDS_Shape>> ShapesToCombine;
{
ShapeSavingEntityCollector savingCollector(*this, ShapesToCombine);
@@ -186,31 +197,18 @@ void ImpExpDxfRead::setOptions()
m_preserveColors = hGrp->GetBool("dxfGetOriginalColors", true);
m_stats.importSettings["Use colors from the DXF file"] = m_preserveColors ? "Yes" : "No";
// Default for creation type is to create draft objects.
// The radio-button structure of the options dialog should generally prevent this condition.
m_mergeOption = DraftObjects;
m_stats.importSettings["Merge option"] = "Create Draft objects"; // Default
if (hGrp->GetBool("groupLayers", true)) {
// Group all compatible objects together
m_mergeOption = MergeShapes;
m_stats.importSettings["Merge option"] = "Group layers into blocks";
}
else if (hGrp->GetBool("dxfCreatePart", true)) {
// Create (non-draft) Shape objects when possible
m_mergeOption = SingleShapes;
m_stats.importSettings["Merge option"] = "Create Part shapes";
}
else if (hGrp->GetBool("dxfCreateDraft", true)) {
// Create only Draft objects, making the result closest to drawn-from-scratch
m_mergeOption = DraftObjects;
m_stats.importSettings["Merge option"] = "Create Draft objects";
}
// Read the new master import mode parameter, set the default.
int mode = hGrp->GetInt("DxfImportMode", static_cast<int>(ImportMode::IndividualShapes));
m_importMode = static_cast<ImportMode>(mode);
// TODO: joingeometry should give an intermediate between MergeShapes and SingleShapes which
// will merge shapes that happen to join end-to-end. As such it should be in the radio button
// set, except that the legacy importer can do joining either for sketches or for shapes. What
// this really means is there should be an "Import as sketch" checkbox, and only the
// MergeShapes, JoinShapes, and SingleShapes radio buttons should be allowed, i.e. Draft Objects
// would be ignored.
// Update: The "Join geometry" option is now a checkbox that is only enabled for the legacy
// importer. Whether the modern importer should support this is still up for debate.
bool joinGeometry = hGrp->GetBool("joingeometry", false);
m_stats.importSettings["Join geometry"] = joinGeometry ? "Yes" : "No";
@@ -604,13 +602,24 @@ void ImpExpDxfRead::OnReadLine(const Base::Vector3d& start,
return;
}
gp_Pnt p0 = makePoint(start);
gp_Pnt p1 = makePoint(end);
if (p0.IsEqual(p1, 0.00000001)) {
// TODO: Really?? What about the people designing integrated circuits?
return;
switch (m_importMode) {
case ImportMode::IndividualShapes:
case ImportMode::FusedShapes: {
gp_Pnt p0 = makePoint(start);
gp_Pnt p1 = makePoint(end);
// TODO: Really?? What about the people designing integrated circuits?
if (p0.IsEqual(p1, 1e-8)) {
return;
}
Collector->AddObject(BRepBuilderAPI_MakeEdge(p0, p1).Edge(), "Line");
break;
}
case ImportMode::EditableDraft:
case ImportMode::EditablePrimitives:
// Do nothing until these modes have been implemented, the one-time warning has already
// been issued.
break;
}
Collector->AddObject(BRepBuilderAPI_MakeEdge(p0, p1).Edge(), "Line");
}
@@ -620,7 +629,19 @@ void ImpExpDxfRead::OnReadPoint(const Base::Vector3d& start)
return;
}
Collector->AddObject(BRepBuilderAPI_MakeVertex(makePoint(start)).Vertex(), "Point");
switch (m_importMode) {
case ImportMode::IndividualShapes:
case ImportMode::FusedShapes: {
// For non-parametric modes, create a Part::Feature with a Vertex shape.
Collector->AddObject(BRepBuilderAPI_MakeVertex(makePoint(start)).Vertex(), "Point");
break;
}
case ImportMode::EditableDraft:
case ImportMode::EditablePrimitives:
// Do nothing until these modes have been implemented, the one-time warning has already
// been issued.
break;
}
}
@@ -634,19 +655,30 @@ void ImpExpDxfRead::OnReadArc(const Base::Vector3d& start,
return;
}
gp_Pnt p0 = makePoint(start);
gp_Pnt p1 = makePoint(end);
gp_Dir up(0, 0, 1);
if (!dir) {
up = -up;
}
gp_Pnt pc = makePoint(center);
gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc));
if (circle.Radius() > 0) {
Collector->AddObject(BRepBuilderAPI_MakeEdge(circle, p0, p1).Edge(), "Arc");
}
else {
Base::Console().warning("ImpExpDxf - ignore degenerate arc of circle\n");
switch (m_importMode) {
case ImportMode::IndividualShapes:
case ImportMode::FusedShapes: {
gp_Pnt p0 = makePoint(start);
gp_Pnt p1 = makePoint(end);
gp_Dir up(0, 0, 1);
if (!dir) {
up.Reverse();
}
gp_Pnt pc = makePoint(center);
gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc));
if (circle.Radius() > 1e-9) {
Collector->AddObject(BRepBuilderAPI_MakeEdge(circle, p0, p1).Edge(), "Arc");
}
else {
Base::Console().warning("ImpExpDxf - ignore degenerate arc of circle\n");
}
break;
}
case ImportMode::EditableDraft:
case ImportMode::EditablePrimitives:
// Do nothing until these modes have been implemented, the one-time warning has already
// been issued.
break;
}
}
@@ -660,18 +692,27 @@ void ImpExpDxfRead::OnReadCircle(const Base::Vector3d& start,
return;
}
gp_Pnt p0 = makePoint(start);
gp_Dir up(0, 0, 1);
if (!dir) {
up = -up;
}
gp_Pnt pc = makePoint(center);
gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc));
if (circle.Radius() > 0) {
Collector->AddObject(BRepBuilderAPI_MakeEdge(circle).Edge(), "Circle");
}
else {
Base::Console().warning("ImpExpDxf - ignore degenerate circle\n");
switch (m_importMode) {
case ImportMode::IndividualShapes:
case ImportMode::FusedShapes: {
gp_Pnt p0 = makePoint(start);
gp_Dir up(0, 0, 1);
if (!dir) {
up.Reverse();
}
gp_Pnt pc = makePoint(center);
gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc));
if (circle.Radius() > 1e-9) {
Collector->AddObject(BRepBuilderAPI_MakeEdge(circle).Edge(), "Circle");
}
else {
Base::Console().warning("ImpExpDxf - ignore degenerate circle\n");
}
break;
}
case ImportMode::EditableDraft:
case ImportMode::EditablePrimitives:
break;
}
}
@@ -776,23 +817,32 @@ void ImpExpDxfRead::OnReadSpline(struct SplineData& sd)
return;
}
try {
Handle(Geom_BSplineCurve) geom;
if (sd.control_points > 0) {
geom = getSplineFromPolesAndKnots(sd);
}
else if (sd.fit_points > 0) {
geom = getInterpolationSpline(sd);
}
switch (m_importMode) {
case ImportMode::IndividualShapes:
case ImportMode::FusedShapes: {
try {
Handle(Geom_BSplineCurve) geom;
if (sd.control_points > 0) {
geom = getSplineFromPolesAndKnots(sd);
}
else if (sd.fit_points > 0) {
geom = getInterpolationSpline(sd);
}
if (geom.IsNull()) {
throw Standard_Failure();
}
if (geom.IsNull()) {
throw Standard_Failure();
}
Collector->AddObject(BRepBuilderAPI_MakeEdge(geom).Edge(), "Spline");
}
catch (const Standard_Failure&) {
Base::Console().warning("ImpExpDxf - failed to create bspline\n");
Collector->AddObject(BRepBuilderAPI_MakeEdge(geom).Edge(), "Spline");
}
catch (const Standard_Failure&) {
Base::Console().warning("ImpExpDxf - failed to create bspline\n");
}
break;
}
case ImportMode::EditableDraft:
case ImportMode::EditablePrimitives:
break;
}
}
@@ -810,22 +860,30 @@ void ImpExpDxfRead::OnReadEllipse(const Base::Vector3d& center,
return;
}
gp_Dir up(0, 0, 1);
if (!dir) {
up = -up;
}
gp_Pnt pc = makePoint(center);
gp_Elips ellipse(gp_Ax2(pc, up), major_radius, minor_radius);
ellipse.Rotate(gp_Ax1(pc, up), rotation);
if (ellipse.MinorRadius() > 0) {
Collector->AddObject(BRepBuilderAPI_MakeEdge(ellipse).Edge(), "Ellipse");
}
else {
Base::Console().warning("ImpExpDxf - ignore degenerate ellipse\n");
switch (m_importMode) {
case ImportMode::IndividualShapes:
case ImportMode::FusedShapes: {
gp_Dir up(0, 0, 1);
if (!dir) {
up.Reverse();
}
gp_Pnt pc = makePoint(center);
gp_Elips ellipse(gp_Ax2(pc, up), major_radius, minor_radius);
ellipse.Rotate(gp_Ax1(pc, up), rotation);
if (ellipse.MinorRadius() > 1e-9) {
Collector->AddObject(BRepBuilderAPI_MakeEdge(ellipse).Edge(), "Ellipse");
}
else {
Base::Console().warning("ImpExpDxf - ignore degenerate ellipse\n");
}
break;
}
case ImportMode::EditableDraft:
case ImportMode::EditablePrimitives:
break;
}
}
void ImpExpDxfRead::OnReadText(const Base::Vector3d& point,
const double height,
const std::string& text,
@@ -901,10 +959,10 @@ void ImpExpDxfRead::OnReadDimension(const Base::Vector3d& start,
PyObject* draftModule = getDraftModule();
if (draftModule != nullptr) {
// TODO: Capture and apply OCSOrientationTransform to OCS coordinates
// Note, some of the locations in the DXF are OCS and some are UCS, but UCS doesn't
// mean UCS when in a block expansion, it means 'transform'
// So we want transform*vector for "UCS" coordinates and transform*ocdCapture*vector
// for "OCS" coordinates
// Note, some of the locations in the DXF are OCS and some are UCS, but UCS
// doesn't mean UCS when in a block expansion, it means 'transform' So we want
// transform*vector for "UCS" coordinates and transform*ocdCapture*vector for
// "OCS" coordinates
//
// We implement the transform by mapping all the points from OCS to UCS
// TODO: Set the Normal property to transform*(0,0,1,0)
@@ -941,6 +999,11 @@ void ImpExpDxfRead::OnReadPolyline(std::list<VertexInfo>& vertices, int flags)
return;
}
// Polyline explosion logic is complex and calls back to other OnRead... handlers.
// The mode switch should happen inside the final geometry creation handlers
// (OnReadLine, OnReadArc), so this function doesn't need its own switch statement.
// It simply acts as a dispatcher.
std::map<CDxfRead::CommonEntityAttributes, std::list<TopoDS_Shape>> ShapesToCombine;
{
// TODO: Currently ExpandPolyline calls OnReadArc etc to generate the pieces, and these
@@ -948,20 +1011,19 @@ void ImpExpDxfRead::OnReadPolyline(std::list<VertexInfo>& vertices, int flags)
// Eventually when m_mergeOption being DraftObjects is implemented OnReadArc etc might
// generate Draft objects which ShapeSavingEntityCollector does not save.
// We need either a collector that collects everything (and we have to figure out
// how to join Draft objects) or we need to temporarily set m_mergeOption to SingleShapes
// if it is set to DraftObjects (and safely restore it on exceptions)
// A clean way would be to give the collector a "makeDraftObjects" property,
// and our special collector could give this the value 'false' whereas the main
// collector would base this on the option setting.
// Also ShapeSavingEntityCollector classifies by entityAttributes which is not needed here
// because they are constant throughout.
// how to join Draft objects) or we need to temporarily set m_mergeOption to
// SingleShapes if it is set to DraftObjects (and safely restore it on exceptions) A
// clean way would be to give the collector a "makeDraftObjects" property, and our
// special collector could give this the value 'false' whereas the main collector would
// base this on the option setting. Also ShapeSavingEntityCollector classifies by
// entityAttributes which is not needed here because they are constant throughout.
ShapeSavingEntityCollector savingCollector(*this, ShapesToCombine);
ExplodePolyline(vertices, flags);
}
// Join the shapes.
if (!ShapesToCombine.empty()) {
// TODO: If we want Draft objects and all segments are straight lines we can make a draft
// wire.
// TODO: If we want Draft objects and all segments are straight lines we can make a
// draft wire.
CombineShapes(ShapesToCombine.begin()->second, "Polyline");
}
}
@@ -1013,12 +1075,12 @@ ImpExpDxfRead::MakeLayer(const std::string& name, ColorIndex_t color, std::strin
PyObject* layer = nullptr;
draftModule = getDraftModule();
if (draftModule != nullptr) {
// After the colours, I also want to pass the draw_style, but there is an intervening
// line-width parameter. It is easier to just pass that parameter's default value than
// to do the handstands to pass a named parameter.
// After the colours, I also want to pass the draw_style, but there is an
// intervening line-width parameter. It is easier to just pass that parameter's
// default value than to do the handstands to pass a named parameter.
// TODO: Pass the appropriate draw_style (from "Solid" "Dashed" "Dotted" "DashDot")
// This needs an ObjectDrawStyleName analogous to ObjectColor but at the ImpExpDxfGui
// level.
// This needs an ObjectDrawStyleName analogous to ObjectColor but at the
// ImpExpDxfGui level.
layer =
// NOLINTNEXTLINE(readability/nolint)
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
@@ -1043,9 +1105,9 @@ ImpExpDxfRead::MakeLayer(const std::string& name, ColorIndex_t color, std::strin
Py_False);
}
// We make our own layer class even if we could not make a layer. MoveToLayer will ignore
// such layers but we have to do this because it is not a polymorphic type so we can't tell
// what we pull out of m_entityAttributes.m_Layer.
// We make our own layer class even if we could not make a layer. MoveToLayer will
// ignore such layers but we have to do this because it is not a polymorphic type so we
// can't tell what we pull out of m_entityAttributes.m_Layer.
return result;
}
return CDxfRead::MakeLayer(name, color, std::move(lineType));
@@ -1055,8 +1117,8 @@ void ImpExpDxfRead::MoveToLayer(App::DocumentObject* object) const
if (m_preserveLayers) {
static_cast<Layer*>(m_entityAttributes.m_Layer)->Contents.push_back(object);
}
// TODO: else Hide the object if it is in a Hidden layer? That won't work because we've cleared
// out m_entityAttributes.m_Layer
// TODO: else Hide the object if it is in a Hidden layer? That won't work because we've
// cleared out m_entityAttributes.m_Layer
}
@@ -1111,7 +1173,8 @@ void ImpExpDxfRead::DrawingEntityCollector::AddObject(App::DocumentObject* obj,
const char* /*nameBase*/)
{
// This overload is for C++ created objects like App::Link
// The object is already in the document, so we just need to style it and move it to a layer.
// The object is already in the document, so we just need to style it and move it to a
// layer.
Reader.MoveToLayer(obj);
// Safely apply styles by checking the object's actual type

View File

@@ -40,6 +40,15 @@ class BRepAdaptor_Curve;
namespace Import
{
enum class ImportMode
{
EditableDraft,
EditablePrimitives,
IndividualShapes,
FusedShapes
};
class ImportExport ImpExpDxfRead: public CDxfRead
{
public:
@@ -108,6 +117,7 @@ public:
void FinishImport() override;
private:
ImportMode m_importMode = ImportMode::IndividualShapes;
bool shouldSkipEntity() const
{
// This entity is in paper space, and the user setting says to ignore it.
@@ -370,7 +380,6 @@ protected:
private:
const EntityCollector* previousEntityCollector;
const eEntityMergeType_t previousMmergeOption;
};
#endif
class BlockDefinitionCollector: public EntityCollector