Skip to content

Commit

Permalink
Part: Add AttacherEngine of type PropertyEnumeration
Browse files Browse the repository at this point in the history
This is added to conveniently change the attacher type of a Part object.

Hint: A new property is used to avoid to break project files when opening it with an older version.

See also forum thread: https://forum.freecad.org/viewtopic.php?t=87891
  • Loading branch information
wwmayer committed May 31, 2024
1 parent 6ea5c79 commit 1786a7e
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/App/GeoFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ const std::vector<const char*>& GeoFeature::getElementTypes(bool /*all*/) const
if (!prop) {
return nil;
}
return prop->getComplexData()->getElementTypes();
return nil;//prop->getComplexData()->getElementTypes();
}

std::vector<Data::IndexedName> GeoFeature::getHigherElements(const char* element, bool silent) const
Expand Down
68 changes: 66 additions & 2 deletions src/Mod/Part/App/AttachExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,59 @@
using namespace Part;
using namespace Attacher;

namespace
{
std::vector<std::string> EngineEnums = {"Engine 3D",
"Engine Plane",
"Engine Line",
"Engine Point"};

const char* enumToClass(const char* mode)
{
if (EngineEnums.at(0) == mode) {
return "Attacher::AttachEngine3D";
}
if (EngineEnums.at(1) == mode) {
return "Attacher::AttachEnginePlane";
}
if (EngineEnums.at(2) == mode) {
return "Attacher::AttachEngineLine";
}
if (EngineEnums.at(3) == mode) {
return "Attacher::AttachEnginePoint";
}

return "Attacher::AttachEngine3D";
}

const char* classToEnum(const char* type)
{
if (strcmp(type, "Attacher::AttachEngine3D") == 0) {
return EngineEnums.at(0).c_str();
}
if (strcmp(type, "Attacher::AttachEnginePlane") == 0) {
return EngineEnums.at(1).c_str();
}
if (strcmp(type, "Attacher::AttachEngineLine") == 0) {
return EngineEnums.at(2).c_str();
}
if (strcmp(type, "Attacher::AttachEnginePoint") == 0) {
return EngineEnums.at(3).c_str();
}

return EngineEnums.at(0).c_str();
}

void restoreAttacherEngine(AttachExtension* self)
{
const char* mode = enumToClass(self->AttacherEngine.getValueAsString());
const char* type = self->AttacherType.getValue();
if (strcmp(mode, type) != 0) {
self->AttacherEngine.setValue(classToEnum(type));
}
}
}

EXTENSION_PROPERTY_SOURCE(Part::AttachExtension, App::DocumentObjectExtension)

#ifdef FC_USE_TNP_FIX
Expand All @@ -41,9 +94,15 @@ AttachExtension::AttachExtension()
EXTENSION_ADD_PROPERTY_TYPE(AttacherType,
("Attacher::AttachEngine3D"),
"Attachment",
(App::PropertyType)(App::Prop_None),
(App::PropertyType)(App::Prop_ReadOnly | App::Prop_Hidden),
"Class name of attach engine object driving the attachment.");
this->AttacherType.setStatus(App::Property::Status::Hidden, true);

EXTENSION_ADD_PROPERTY_TYPE(AttacherEngine,
(0L),
"Attachment",
(App::PropertyType)(App::Prop_None),
"Attach engine object driving the attachment.");
AttacherEngine.setEnums(EngineEnums);

EXTENSION_ADD_PROPERTY_TYPE(
Support,
Expand Down Expand Up @@ -354,6 +413,9 @@ void AttachExtension::extensionOnChanged(const App::Property* prop)
AttachmentSupport.Paste(Support);
}
}
else if (prop == &AttacherEngine) {
AttacherType.setValue(enumToClass(AttacherEngine.getValueAsString()));
}
else if (_props.matchProperty(prop)) {
if (prop == &AttachmentSupport) {
Base::ObjectStatusLocker<App::Property::Status, App::Property> guard(
Expand Down Expand Up @@ -407,6 +469,8 @@ void AttachExtension::onExtendedDocumentRestored()
}
_active = -1;
updatePropertyStatus(isAttacherActive());

restoreAttacherEngine(this);
}
catch (Base::Exception&) {
}
Expand Down
1 change: 1 addition & 0 deletions src/Mod/Part/App/AttachExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class PartExport AttachExtension: public App::DocumentObjectExtension
Attacher::AttachEngine& attacher(bool base = false) const;

App::PropertyString AttacherType;
App::PropertyEnumeration AttacherEngine;
App::PropertyLinkSubList Support; // deprecated, leave here for backward compatibility
App::PropertyLinkSubList AttachmentSupport;
App::PropertyEnumeration MapMode; // see AttachEngine::eMapMode
Expand Down
42 changes: 42 additions & 0 deletions tests/src/Mod/Part/App/AttachExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,45 @@ TEST_F(AttachExtensionTest, testPlanePlane)
getDocument()->recompute();
EXPECT_TRUE(true);
}

TEST_F(AttachExtensionTest, testAttacherEngineType)
{
auto plane = dynamic_cast<Part::Plane*>(getDocument()->addObject("Part::Plane", "Plane"));
EXPECT_STREQ(plane->AttacherType.getValue(), "Attacher::AttachEngine3D");
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine 3D");

plane->AttacherEngine.setValue(1L);
EXPECT_STREQ(plane->AttacherType.getValue(), "Attacher::AttachEnginePlane");
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine Plane");

plane->AttacherEngine.setValue(2L);
EXPECT_STREQ(plane->AttacherType.getValue(), "Attacher::AttachEngineLine");
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine Line");

plane->AttacherEngine.setValue(3L);
EXPECT_STREQ(plane->AttacherType.getValue(), "Attacher::AttachEnginePoint");
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine Point");
}

TEST_F(AttachExtensionTest, testAttacherTypeEngine)
{
auto plane = dynamic_cast<Part::Plane*>(getDocument()->addObject("Part::Plane", "Plane"));
EXPECT_STREQ(plane->AttacherType.getValue(), "Attacher::AttachEngine3D");
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine 3D");

plane->AttacherType.setValue("Attacher::AttachEnginePlane");
plane->onExtendedDocumentRestored();
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine Plane");

plane->AttacherType.setValue("Attacher::AttachEngineLine");
plane->onExtendedDocumentRestored();
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine Line");

plane->AttacherType.setValue("Attacher::AttachEnginePoint");
plane->onExtendedDocumentRestored();
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine Point");

plane->AttacherType.setValue("Attacher::AttachEngine3D");
plane->onExtendedDocumentRestored();
EXPECT_STREQ(plane->AttacherEngine.getValueAsString(), "Engine 3D");
}

0 comments on commit 1786a7e

Please sign in to comment.