Handle all combos of "group into blocks" "use DXF colors" "use layers"

Fixes #11873 this was the primary goal of these changes

Fixes (partially) #11874 the parts of a polyline are combined as a
compound object (shape) but it would be preferable for them to be made
into a wire (if possible)

Fixes #11872 Objects in a block definition are now kept separately
until the block is inserted, in which case the inserted objects are
subject to all the other options regarding combining.

Fixes (partially, review required) #11871 Text and dimensions are now
kept as part of the block definition and are placed in the drawing when
the block is inserted but this code has not been extensively tested.

Affects #11875, custom types are not made, but the labels now reflect
the object types rather than all being "Shapennn"

This leaves the importer options handling in a bit of a mess that needs
cleanup eventually, but this can be a new issue.
This includes some importer flags that have no corresponding options
(e.g. import frozen layers), some flags not yet implemented, some
flags not yet even declared in the code because their implementation
is further off (import hatch outlines), and some suggested future
options (import SOLIDs as faces)

Centralize the calculation of the OCS for entities as they're read
from the DXF. Most of the entities don't use this yet, but some of
them roll their own crude Normal Vector handling. Because the new
code takes priority over the old for reading the normal vector, such
code will always see (0, 0, 1) as the extrusion direction.
This commit is contained in:
Kevin Martin
2024-01-10 09:07:03 -05:00
committed by Yorik van Havre
parent c57a83cb4f
commit 0dcfe94505
6 changed files with 1041 additions and 272 deletions

View File

@@ -49,17 +49,8 @@
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#endif
#include <regex>
// #include <App/Annotation.h>
// #include <App/Application.h>
// #include <App/Document.h>
// #include <Base/Console.h>
// #include <Base/Interpreter.h>
// #include <Base/Matrix.h>
// #include <Base/Parameter.h>
// #include <Base/Vector3D.h>
// #include <Base/PlacementPy.h>
// #include <Mod/Part/App/PartFeature.h>
#include <Gui/Application.h>
#include <Gui/ViewProvider.h>
#include <Gui/ViewProviderDocumentObject.h>
@@ -69,28 +60,28 @@
using namespace ImportGui;
ImpExpDxfReadGui::ImpExpDxfReadGui(std::string filepath, App::Document* pcDoc)
ImpExpDxfReadGui::ImpExpDxfReadGui(const std::string& filepath, App::Document* pcDoc)
: ImpExpDxfRead(filepath, pcDoc)
, GuiDocument(Gui::Application::Instance->getDocument(pcDoc))
{}
void ImpExpDxfReadGui::ApplyGuiStyles(Part::Feature* object)
void ImpExpDxfReadGui::ApplyGuiStyles(Part::Feature* object) const
{
PartGui::ViewProviderPart* view =
static_cast<PartGui::ViewProviderPart*>(GuiDocument->getViewProvider(object));
App::Color color = ObjectColor();
auto view = static_cast<PartGui::ViewProviderPart*>(GuiDocument->getViewProvider(object));
App::Color color = ObjectColor(m_entityAttributes.m_Color);
view->LineColor.setValue(color);
view->PointColor.setValue(color);
view->ShapeColor.setValue(color);
view->DrawStyle.setValue(GetDrawStyle());
view->Transparency.setValue(0);
}
void ImpExpDxfReadGui::ApplyGuiStyles(App::FeaturePython* object)
void ImpExpDxfReadGui::ApplyGuiStyles(App::FeaturePython* object) const
{
static Base::Type PropertyColorType = App::PropertyColor::getClassTypeId();
auto view = static_cast<Gui::ViewProviderDocumentObject*>(GuiDocument->getViewProvider(object));
App::Color color = ObjectColor();
App::Color color = ObjectColor(m_entityAttributes.m_Color);
// The properties on this object depend on which Python object is wrapped around it.
// For now we look for the two colors we expect in text and dimensions, and check that they
@@ -105,4 +96,50 @@ void ImpExpDxfReadGui::ApplyGuiStyles(App::FeaturePython* object)
if (prop != nullptr && prop->getTypeId() == PropertyColorType) {
static_cast<App::PropertyColor*>(prop)->setValue(color);
}
prop = view->getPropertyByName("DrawStyle");
if (prop != nullptr && prop->getTypeId() == PropertyColorType) {
static_cast<App::PropertyColor*>(prop)->setValue(GetDrawStyle());
}
}
int ImpExpDxfReadGui::GetDrawStyle() const
{
// The DXF line type can be quite complex, including both patterns, in-line text (for instance,
// so a line can mark itself as "Gas Main"), and shapes from a .SHX file (so a line can have,
// say, diamond shapes along it). The coin package we use to render objects into the screen has
// no facility for doing the in-line text or shapes, and has limited control over line/space
// patterns. The line pattern is divided into 16 pieces which can be either drawn or not. There
// is also support for line pattern scaling (to match the LTSCALE DXF property). Unfortunately
// neither of these is exposed at the FreeCAD level; line types are dumbed down to four choices:
// 0 "Solid" 0xffff i.e. solid
// 1 "Dashed" 0xf00f i.e. coarse dashes
// 2 "Dotted" 0x0f0f i.e. fine (half-size) dashes
// 3 "DashDot" 0xff88 i.e. long dash/dot (like a center line)
// Right now we infer these from the DXF LINETYPE name. In the long run we should look at the
// actual pattern, but the CDxfRead class does nothing with the LTYPE table. In the longer run,
// FreeCAD should expose the line pattern (the 16-bit number) for more versatility.
// Make an array of patterns whose index is the "draw style" enum value for the pattern.
static std::array<std::regex, 4> matchers {
// Starts with "cont" (i.e. continuous) : return solid
// I can't find anything that actually says what happens if you have a top-level (i.e. not
// in a BLOCK) object whose line type is BYBLOCK. We treat this as Continuous.
std::basic_regex("^cont|^byblock$", std::regex::icase),
// starts with hidden, border, dash : return dashed
std::basic_regex("^hidden|^border|^dash", std::regex::icase),
// starts with dot : return dotted
std::basic_regex("^dot", std::regex::icase),
// dash & dot or center/centre/divide/phantom : return DashDot
std::basic_regex("dot.*dash|dash.*dot|^cent(er|re)|^divide|^phantom", std::regex::icase)};
// Some line type names can match several patterns, in particular dotdash can also match ^dot
// and dashdot can match ^dash Rather than code the latter patterns to forbid subsequent "dash"
// or "dot" so they are mutually exclusive, we just match the more specific pattern, which is
// the last one, first.
for (int i = matchers.size(); --i >= 0;) {
if (regex_search(m_entityAttributes.m_LineType, matchers.at(i))) {
return i;
}
}
// If we don't understand it, return solid
return 0;
}

View File

@@ -37,14 +37,15 @@ namespace ImportGui
class ImpExpDxfReadGui: public Import::ImpExpDxfRead
{
public:
ImpExpDxfReadGui(std::string filepath, App::Document* pcDoc);
ImpExpDxfReadGui(const std::string& filepath, App::Document* pcDoc);
protected:
void ApplyGuiStyles(Part::Feature* object) override;
void ApplyGuiStyles(App::FeaturePython* object) override;
void ApplyGuiStyles(Part::Feature* object) const override;
void ApplyGuiStyles(App::FeaturePython* object) const override;
private:
Gui::Document* GuiDocument;
int GetDrawStyle() const;
};
} // namespace ImportGui