[PD] shape binder: code style improvements
all done by MSVC
This commit is contained in:
@@ -46,7 +46,7 @@
|
||||
FC_LOG_LEVEL_INIT("PartDesign",true,true)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
using namespace PartDesign;
|
||||
@@ -58,7 +58,7 @@ PROPERTY_SOURCE(PartDesign::ShapeBinder, Part::Feature)
|
||||
|
||||
ShapeBinder::ShapeBinder()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(Support, (nullptr,nullptr), "",(App::PropertyType)(App::Prop_None),"Support of the geometry");
|
||||
ADD_PROPERTY_TYPE(Support, (nullptr, nullptr), "", (App::PropertyType)(App::Prop_None), "Support of the geometry");
|
||||
Placement.setStatus(App::Property::Hidden, true);
|
||||
ADD_PROPERTY_TYPE(TraceSupport, (false), "", App::Prop_None, "Trace support shape");
|
||||
}
|
||||
@@ -99,9 +99,9 @@ Part::TopoShape ShapeBinder::updatedShape() const
|
||||
if (TraceSupport.getValue()) {
|
||||
//compute the transform, and apply it to the shape.
|
||||
Base::Placement sourceCS = //full placement of container of obj
|
||||
obj->globalPlacement() * obj->Placement.getValue().inverse();
|
||||
obj->globalPlacement() * obj->Placement.getValue().inverse();
|
||||
Base::Placement targetCS = //full placement of container of this shapebinder
|
||||
this->globalPlacement() * this->Placement.getValue().inverse();
|
||||
this->globalPlacement() * this->Placement.getValue().inverse();
|
||||
Base::Placement transform = targetCS.inverse() * sourceCS;
|
||||
shape.setPlacement(transform * shape.getPlacement());
|
||||
}
|
||||
@@ -214,7 +214,7 @@ Part::TopoShape ShapeBinder::buildShapeFromReferences(App::GeoFeature* obj, std:
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound cmp;
|
||||
builder.MakeCompound(cmp);
|
||||
for(const TopoDS_Shape& sh : shapes){
|
||||
for (const TopoDS_Shape& sh : shapes) {
|
||||
builder.Add(cmp, sh);
|
||||
}
|
||||
return cmp;
|
||||
@@ -238,7 +238,7 @@ Part::TopoShape ShapeBinder::buildShapeFromReferences(App::GeoFeature* obj, std:
|
||||
return TopoDS_Shape();
|
||||
}
|
||||
|
||||
void ShapeBinder::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop)
|
||||
void ShapeBinder::handleChangedPropertyType(Base::XMLReader& reader, const char* TypeName, App::Property* prop)
|
||||
{
|
||||
// The type of Support was App::PropertyLinkSubList in the past
|
||||
if (prop == &Support && strcmp(TypeName, "App::PropertyLinkSubList") == 0) {
|
||||
@@ -303,56 +303,56 @@ PROPERTY_SOURCE(PartDesign::SubShapeBinder, Part::Feature)
|
||||
|
||||
SubShapeBinder::SubShapeBinder()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(Support, (nullptr), "",(App::PropertyType)(App::Prop_None), "Support of the geometry");
|
||||
ADD_PROPERTY_TYPE(Support, (nullptr), "", (App::PropertyType)(App::Prop_None), "Support of the geometry");
|
||||
Support.setStatus(App::Property::ReadOnly, true);
|
||||
ADD_PROPERTY_TYPE(Fuse, (false), "Base",App::Prop_None,"Fuse solids from bound shapes");
|
||||
ADD_PROPERTY_TYPE(MakeFace, (true), "Base",App::Prop_None,"Create face using wires from bound shapes");
|
||||
ADD_PROPERTY_TYPE(Fuse, (false), "Base", App::Prop_None, "Fuse solids from bound shapes");
|
||||
ADD_PROPERTY_TYPE(MakeFace, (true), "Base", App::Prop_None, "Create face using wires from bound shapes");
|
||||
ADD_PROPERTY_TYPE(Offset, (0.0), "Offsetting", App::Prop_None, "2D offset face or wires, 0.0 = no offset");
|
||||
ADD_PROPERTY_TYPE(OffsetJoinType, ((long)0), "Offsetting", App::Prop_None, "Arcs, Tangent, Intersection");
|
||||
static const char*JoinTypeEnum[] = {"Arcs", "Tangent", "Intersection", nullptr};
|
||||
static const char* JoinTypeEnum[] = { "Arcs", "Tangent", "Intersection", nullptr };
|
||||
OffsetJoinType.setEnums(JoinTypeEnum);
|
||||
ADD_PROPERTY_TYPE(OffsetFill, (false),"Offsetting", App::Prop_None, "True = make face between original wire and offset.");
|
||||
ADD_PROPERTY_TYPE(OffsetFill, (false), "Offsetting", App::Prop_None, "True = make face between original wire and offset.");
|
||||
ADD_PROPERTY_TYPE(OffsetOpenResult, (false), "Offsetting", App::Prop_None, "False = make closed offset from open wire.");
|
||||
ADD_PROPERTY_TYPE(OffsetIntersection, (false), "Offsetting", App::Prop_None, "False = offset child wires independently.");
|
||||
ADD_PROPERTY_TYPE(ClaimChildren, (false), "Base",App::Prop_Output,"Claim linked object as children");
|
||||
ADD_PROPERTY_TYPE(Relative, (true), "Base",App::Prop_None,"Enable relative sub-object binding");
|
||||
ADD_PROPERTY_TYPE(BindMode, ((long)0), "Base", App::Prop_None,
|
||||
"Synchronized: auto update binder shape on changed of bound object.\n"
|
||||
"Frozen: disable auto update, but can be updated manually using context menu.\n"
|
||||
"Detached: copy the shape of bound object and then remove the binding immediately.");
|
||||
ADD_PROPERTY_TYPE(ClaimChildren, (false), "Base", App::Prop_Output, "Claim linked object as children");
|
||||
ADD_PROPERTY_TYPE(Relative, (true), "Base", App::Prop_None, "Enable relative sub-object binding");
|
||||
ADD_PROPERTY_TYPE(BindMode, ((long)0), "Base", App::Prop_None,
|
||||
"Synchronized: auto update binder shape on changed of bound object.\n"
|
||||
"Frozen: disable auto update, but can be updated manually using context menu.\n"
|
||||
"Detached: copy the shape of bound object and then remove the binding immediately.");
|
||||
ADD_PROPERTY_TYPE(PartialLoad, (false), "Base", App::Prop_None,
|
||||
"Enable partial loading, which disables auto loading of external document for"
|
||||
"external bound object.");
|
||||
PartialLoad.setStatus(App::Property::PartialTrigger,true);
|
||||
static const char *BindModeEnum[] = {"Synchronized", "Frozen", "Detached", nullptr};
|
||||
"Enable partial loading, which disables auto loading of external document for"
|
||||
"external bound object.");
|
||||
PartialLoad.setStatus(App::Property::PartialTrigger, true);
|
||||
static const char* BindModeEnum[] = { "Synchronized", "Frozen", "Detached", nullptr };
|
||||
BindMode.setEnums(BindModeEnum);
|
||||
|
||||
ADD_PROPERTY_TYPE(Context, (nullptr), "Base", App::Prop_Hidden,
|
||||
"Stores the context of this binder. It is used for monitoring and auto updating\n"
|
||||
"the relative placement of the bound shape");
|
||||
"Stores the context of this binder. It is used for monitoring and auto updating\n"
|
||||
"the relative placement of the bound shape");
|
||||
|
||||
static const char *BindCopyOnChangeEnum[] = {"Disabled", "Enabled", "Mutated", nullptr};
|
||||
static const char* BindCopyOnChangeEnum[] = { "Disabled", "Enabled", "Mutated", nullptr };
|
||||
BindCopyOnChange.setEnums(BindCopyOnChangeEnum);
|
||||
ADD_PROPERTY_TYPE(BindCopyOnChange, ((long)0), "Base", App::Prop_None,
|
||||
"Disabled: disable copy on change.\n"
|
||||
"Enabled: duplicate properties from binding object that are marked with 'CopyOnChange'.\n"
|
||||
" Make internal copy of the object with any changed properties to obtain the\n"
|
||||
" shape of an alternative configuration\n"
|
||||
"Mutated: indicate the binder has already mutated by changing any properties marked with\n"
|
||||
" 'CopyOnChange'. Those properties will not longer be kept in sync between the\n"
|
||||
" binder and the binding object");
|
||||
"Disabled: disable copy on change.\n"
|
||||
"Enabled: duplicate properties from binding object that are marked with 'CopyOnChange'.\n"
|
||||
" Make internal copy of the object with any changed properties to obtain the\n"
|
||||
" shape of an alternative configuration\n"
|
||||
"Mutated: indicate the binder has already mutated by changing any properties marked with\n"
|
||||
" 'CopyOnChange'. Those properties will not longer be kept in sync between the\n"
|
||||
" binder and the binding object");
|
||||
|
||||
ADD_PROPERTY_TYPE(Refine,(true),"Base",(App::PropertyType)(App::Prop_None),
|
||||
"Refine shape (clean up redundant edges) after adding/subtracting");
|
||||
ADD_PROPERTY_TYPE(Refine, (true), "Base", (App::PropertyType)(App::Prop_None),
|
||||
"Refine shape (clean up redundant edges) after adding/subtracting");
|
||||
|
||||
Context.setScope(App::LinkScope::Hidden);
|
||||
|
||||
ADD_PROPERTY_TYPE(_Version,(0),"Base",(App::PropertyType)(
|
||||
App::Prop_Hidden|App::Prop_ReadOnly), "");
|
||||
ADD_PROPERTY_TYPE(_Version, (0), "Base", (App::PropertyType)(
|
||||
App::Prop_Hidden | App::Prop_ReadOnly), "");
|
||||
|
||||
_CopiedLink.setScope(App::LinkScope::Hidden);
|
||||
ADD_PROPERTY_TYPE(_CopiedLink,(nullptr),"Base",(App::PropertyType)(
|
||||
App::Prop_Hidden|App::Prop_ReadOnly|App::Prop_NoPersist), "");
|
||||
ADD_PROPERTY_TYPE(_CopiedLink, (nullptr), "Base", (App::PropertyType)(
|
||||
App::Prop_Hidden | App::Prop_ReadOnly | App::Prop_NoPersist), "");
|
||||
}
|
||||
|
||||
SubShapeBinder::~SubShapeBinder() {
|
||||
@@ -373,39 +373,40 @@ void SubShapeBinder::setupObject() {
|
||||
this->Refine.setValue(hGrp->GetBool("RefineModel", false));
|
||||
}
|
||||
|
||||
App::DocumentObject *SubShapeBinder::getSubObject(const char *subname, PyObject **pyObj,
|
||||
Base::Matrix4D *mat, bool transform, int depth) const
|
||||
App::DocumentObject* SubShapeBinder::getSubObject(const char* subname, PyObject** pyObj,
|
||||
Base::Matrix4D* mat, bool transform, int depth) const
|
||||
{
|
||||
auto sobj = Part::Feature::getSubObject(subname,pyObj,mat,transform,depth);
|
||||
if(sobj)
|
||||
auto sobj = Part::Feature::getSubObject(subname, pyObj, mat, transform, depth);
|
||||
if (sobj)
|
||||
return sobj;
|
||||
if(Data::ComplexGeoData::findElementName(subname)==subname)
|
||||
if (Data::ComplexGeoData::findElementName(subname) == subname)
|
||||
return nullptr;
|
||||
|
||||
const char *dot = strchr(subname, '.');
|
||||
if(!dot)
|
||||
const char* dot = strchr(subname, '.');
|
||||
if (!dot)
|
||||
return nullptr;
|
||||
|
||||
App::GetApplication().checkLinkDepth(depth);
|
||||
std::string name(subname,dot-subname);
|
||||
for(auto &l : Support.getSubListValues()) {
|
||||
std::string name(subname, dot - subname);
|
||||
for (auto& l : Support.getSubListValues()) {
|
||||
auto obj = l.getValue();
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
if (!obj || !obj->getNameInDocument())
|
||||
continue;
|
||||
for(auto &sub : l.getSubValues()) {
|
||||
for (auto& sub : l.getSubValues()) {
|
||||
auto sobj = obj->getSubObject(sub.c_str());
|
||||
if(!sobj || !sobj->getNameInDocument())
|
||||
if (!sobj || !sobj->getNameInDocument())
|
||||
continue;
|
||||
if(subname[0] == '$') {
|
||||
if(sobj->Label.getStrValue() != name.c_str()+1)
|
||||
if (subname[0] == '$') {
|
||||
if (sobj->Label.getStrValue() != name.c_str() + 1)
|
||||
continue;
|
||||
} else if(!boost::equals(sobj->getNameInDocument(), name))
|
||||
}
|
||||
else if (!boost::equals(sobj->getNameInDocument(), name))
|
||||
continue;
|
||||
name = Data::ComplexGeoData::noElementName(sub.c_str());
|
||||
name += dot+1;
|
||||
if(mat && transform)
|
||||
name += dot + 1;
|
||||
if (mat && transform)
|
||||
*mat *= Placement.getValue().toMatrix();
|
||||
return obj->getSubObject(name.c_str(),pyObj,mat,true,depth+1);
|
||||
return obj->getSubObject(name.c_str(), pyObj, mat, true, depth + 1);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -414,19 +415,21 @@ App::DocumentObject *SubShapeBinder::getSubObject(const char *subname, PyObject
|
||||
void SubShapeBinder::setupCopyOnChange() {
|
||||
copyOnChangeConns.clear();
|
||||
|
||||
const auto &support = Support.getSubListValues();
|
||||
if(BindCopyOnChange.getValue()==0 || support.size()!=1) {
|
||||
if(hasCopyOnChange) {
|
||||
const auto& support = Support.getSubListValues();
|
||||
if (BindCopyOnChange.getValue() == 0 || support.size() != 1) {
|
||||
if (hasCopyOnChange) {
|
||||
hasCopyOnChange = false;
|
||||
std::vector<App::Property*> props;
|
||||
getPropertyList(props);
|
||||
for(auto prop : props) {
|
||||
if(App::LinkBaseExtension::isCopyOnChangeProperty(this,*prop)) {
|
||||
for (auto prop : props) {
|
||||
if (App::LinkBaseExtension::isCopyOnChangeProperty(this, *prop)) {
|
||||
try {
|
||||
removeDynamicProperty(prop->getName());
|
||||
} catch (Base::Exception &e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
e.ReportException();
|
||||
} catch (...) {
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -435,21 +438,21 @@ void SubShapeBinder::setupCopyOnChange() {
|
||||
}
|
||||
|
||||
auto linked = support.front().getValue();
|
||||
hasCopyOnChange = App::LinkBaseExtension::setupCopyOnChange(this,linked,
|
||||
BindCopyOnChange.getValue()==1?©OnChangeConns:nullptr,hasCopyOnChange);
|
||||
if(hasCopyOnChange) {
|
||||
hasCopyOnChange = App::LinkBaseExtension::setupCopyOnChange(this, linked,
|
||||
BindCopyOnChange.getValue() == 1 ? ©OnChangeConns : nullptr, hasCopyOnChange);
|
||||
if (hasCopyOnChange) {
|
||||
copyOnChangeConns.push_back(linked->signalChanged.connect(
|
||||
[this](const App::DocumentObject &, const App::Property &prop) {
|
||||
if(!prop.testStatus(App::Property::Output)
|
||||
&& !prop.testStatus(App::Property::PropOutput))
|
||||
{
|
||||
if(this->_CopiedObjs.size()) {
|
||||
FC_LOG("Clear binder " << getFullName() << " cache on change of "
|
||||
<< prop.getFullName());
|
||||
this->clearCopiedObjects();
|
||||
}
|
||||
[this](const App::DocumentObject&, const App::Property& prop) {
|
||||
if (!prop.testStatus(App::Property::Output)
|
||||
&& !prop.testStatus(App::Property::PropOutput))
|
||||
{
|
||||
if (this->_CopiedObjs.size()) {
|
||||
FC_LOG("Clear binder " << getFullName() << " cache on change of "
|
||||
<< prop.getFullName());
|
||||
this->clearCopiedObjects();
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -457,9 +460,9 @@ void SubShapeBinder::setupCopyOnChange() {
|
||||
void SubShapeBinder::clearCopiedObjects() {
|
||||
std::vector<App::DocumentObjectT> objs;
|
||||
objs.swap(_CopiedObjs);
|
||||
for(auto &o : objs) {
|
||||
for (auto& o : objs) {
|
||||
auto obj = o.getObject();
|
||||
if(obj)
|
||||
if (obj)
|
||||
obj->getDocument()->removeObject(obj->getNameInDocument());
|
||||
}
|
||||
_CopiedLink.setValue(nullptr);
|
||||
@@ -467,7 +470,7 @@ void SubShapeBinder::clearCopiedObjects() {
|
||||
|
||||
void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
Part::TopoShape result;
|
||||
std::vector<Part ::TopoShape> shapes;
|
||||
std::vector<Part::TopoShape> shapes;
|
||||
std::vector<const Base::Matrix4D*> shapeMats;
|
||||
|
||||
bool forced = (Shape.getValue().IsNull() || (options & UpdateForced)) ? true : false;
|
||||
@@ -475,94 +478,99 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
|
||||
std::string errMsg;
|
||||
auto parent = Context.getValue();
|
||||
std::string parentSub = Context.getSubName(false);
|
||||
if(!Relative.getValue())
|
||||
std::string parentSub = Context.getSubName(false);
|
||||
if (!Relative.getValue())
|
||||
parent = nullptr;
|
||||
else {
|
||||
if (parent && parent->getSubObject(parentSub.c_str())==this) {
|
||||
if (parent && parent->getSubObject(parentSub.c_str()) == this) {
|
||||
auto parents = parent->getParents();
|
||||
if (!parents.empty()) {
|
||||
parent = parents.begin()->first;
|
||||
parentSub = parents.begin()->second + parentSub;
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
parent = nullptr;
|
||||
if (!parent && parentSub.empty()) {
|
||||
auto parents = getParents();
|
||||
if(!parents.empty()) {
|
||||
if (!parents.empty()) {
|
||||
parent = parents.begin()->first;
|
||||
parentSub = parents.begin()->second;
|
||||
}
|
||||
}
|
||||
if(parent && (parent!=Context.getValue() || parentSub!=Context.getSubName(false)))
|
||||
Context.setValue(parent,parentSub.c_str());
|
||||
if (parent && (parent != Context.getValue() || parentSub != Context.getSubName(false)))
|
||||
Context.setValue(parent, parentSub.c_str());
|
||||
}
|
||||
|
||||
bool first = false;
|
||||
std::unordered_map<const App::DocumentObject*, Base::Matrix4D> mats;
|
||||
for(auto &l : Support.getSubListValues()) {
|
||||
for (auto& l : Support.getSubListValues()) {
|
||||
auto obj = l.getValue();
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
if (!obj || !obj->getNameInDocument())
|
||||
continue;
|
||||
auto res = mats.emplace(obj,Base::Matrix4D());
|
||||
if(parent && res.second) {
|
||||
auto res = mats.emplace(obj, Base::Matrix4D());
|
||||
if (parent && res.second) {
|
||||
std::string resolvedSub = parentSub;
|
||||
std::string linkSub;
|
||||
auto link = obj;
|
||||
auto resolved = parent->resolveRelativeLink(resolvedSub,link,linkSub);
|
||||
if(!resolved) {
|
||||
if(!link) {
|
||||
auto resolved = parent->resolveRelativeLink(resolvedSub, link, linkSub);
|
||||
if (!resolved) {
|
||||
if (!link) {
|
||||
FC_WARN(getFullName() << " cannot resolve relative link of "
|
||||
<< parent->getFullName() << '.' << parentSub
|
||||
<< " -> " << obj->getFullName());
|
||||
<< parent->getFullName() << '.' << parentSub
|
||||
<< " -> " << obj->getFullName());
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
Base::Matrix4D mat;
|
||||
auto sobj = resolved->getSubObject(resolvedSub.c_str(),nullptr,&mat);
|
||||
if(sobj!=this) {
|
||||
FC_LOG(getFullName() << " skip invalid parent " << resolved->getFullName()
|
||||
<< '.' << resolvedSub);
|
||||
}else if(_Version.getValue()==0) {
|
||||
auto sobj = resolved->getSubObject(resolvedSub.c_str(), nullptr, &mat);
|
||||
if (sobj != this) {
|
||||
FC_LOG(getFullName() << " skip invalid parent " << resolved->getFullName()
|
||||
<< '.' << resolvedSub);
|
||||
}
|
||||
else if (_Version.getValue() == 0) {
|
||||
// For existing legacy SubShapeBinder, we use its Placement
|
||||
// to store the position adjustment of the first Support
|
||||
if(first) {
|
||||
auto pla = Placement.getValue()*Base::Placement(mat).inverse();
|
||||
if (first) {
|
||||
auto pla = Placement.getValue() * Base::Placement(mat).inverse();
|
||||
Placement.setValue(pla);
|
||||
first = false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// The remaining support will cancel the Placement
|
||||
mat.inverseGauss();
|
||||
res.first->second = mat;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
// For newer SubShapeBinder, the Placement property is free
|
||||
// to use by the user to add additional offset to the
|
||||
// binding object
|
||||
mat.inverseGauss();
|
||||
res.first->second = Placement.getValue().toMatrix()*mat;
|
||||
res.first->second = Placement.getValue().toMatrix() * mat;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(init)
|
||||
if (init)
|
||||
continue;
|
||||
|
||||
App::DocumentObject *copied = nullptr;
|
||||
App::DocumentObject* copied = nullptr;
|
||||
|
||||
if(BindCopyOnChange.getValue() == 2 && Support.getSubListValues().size()==1) {
|
||||
if(_CopiedObjs.size())
|
||||
copied = _CopiedObjs.front().getObject();
|
||||
if (BindCopyOnChange.getValue() == 2 && Support.getSubListValues().size() == 1) {
|
||||
if (_CopiedObjs.size())
|
||||
copied = _CopiedObjs.front().getObject();
|
||||
|
||||
bool recomputeCopy = false;
|
||||
int copyerror = 0;
|
||||
if(!copied || !copied->isValid()) {
|
||||
if (!copied || !copied->isValid()) {
|
||||
recomputeCopy = true;
|
||||
clearCopiedObjects();
|
||||
|
||||
auto tmpDoc = App::GetApplication().newDocument(
|
||||
"_tmp_binder", nullptr, false, true);
|
||||
auto objs = tmpDoc->copyObject({obj},true,true);
|
||||
"_tmp_binder", nullptr, false, true);
|
||||
auto objs = tmpDoc->copyObject({ obj }, true, true);
|
||||
if (!objs.empty()) {
|
||||
for(auto it=objs.rbegin(); it!=objs.rend(); ++it)
|
||||
for (auto it = objs.rbegin(); it != objs.rend(); ++it)
|
||||
_CopiedObjs.emplace_back(*it);
|
||||
copied = objs.back();
|
||||
// IMPORTANT! must make a recomputation first before any
|
||||
@@ -573,60 +581,61 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
}
|
||||
}
|
||||
|
||||
if(copied) {
|
||||
if (copied) {
|
||||
if (!copyerror) {
|
||||
std::vector<App::Property*> props;
|
||||
getPropertyList(props);
|
||||
for(auto prop : props) {
|
||||
if(!App::LinkBaseExtension::isCopyOnChangeProperty(this,*prop))
|
||||
for (auto prop : props) {
|
||||
if (!App::LinkBaseExtension::isCopyOnChangeProperty(this, *prop))
|
||||
continue;
|
||||
auto p = copied->getPropertyByName(prop->getName());
|
||||
if(p && p->getContainer()==copied
|
||||
&& p->getTypeId()==prop->getTypeId()
|
||||
&& !p->isSame(*prop))
|
||||
if (p && p->getContainer() == copied
|
||||
&& p->getTypeId() == prop->getTypeId()
|
||||
&& !p->isSame(*prop))
|
||||
{
|
||||
recomputeCopy = true;
|
||||
std::unique_ptr<App::Property> pcopy(prop->Copy());
|
||||
p->Paste(*pcopy);
|
||||
}
|
||||
}
|
||||
if(recomputeCopy && !copied->recomputeFeature(true))
|
||||
if (recomputeCopy && !copied->recomputeFeature(true))
|
||||
copyerror = 2;
|
||||
}
|
||||
obj = copied;
|
||||
_CopiedLink.setValue(copied,l.getSubValues(false));
|
||||
_CopiedLink.setValue(copied, l.getSubValues(false));
|
||||
if (copyerror) {
|
||||
FC_THROWM(Base::RuntimeError,
|
||||
(copyerror == 1 ? "Initial copy failed." : "Copy on change failed.")
|
||||
<< " Please check report view for more details.\n"
|
||||
"You can show temporary document to reveal the failed objects using\n"
|
||||
"tree view context menu.");
|
||||
(copyerror == 1 ? "Initial copy failed." : "Copy on change failed.")
|
||||
<< " Please check report view for more details.\n"
|
||||
"You can show temporary document to reveal the failed objects using\n"
|
||||
"tree view context menu.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto &subvals = copied?_CopiedLink.getSubValues():l.getSubValues();
|
||||
std::set<std::string> subs(subvals.begin(),subvals.end());
|
||||
const auto& subvals = copied ? _CopiedLink.getSubValues() : l.getSubValues();
|
||||
std::set<std::string> subs(subvals.begin(), subvals.end());
|
||||
static std::string none("");
|
||||
if(subs.empty())
|
||||
if (subs.empty())
|
||||
subs.insert(none);
|
||||
else if(subs.size()>1)
|
||||
else if (subs.size() > 1)
|
||||
subs.erase(none);
|
||||
for(const auto &sub : subs) {
|
||||
for (const auto& sub : subs) {
|
||||
try {
|
||||
auto shape = Part::Feature::getTopoShape(obj,sub.c_str(),true);
|
||||
if(!shape.isNull()) {
|
||||
auto shape = Part::Feature::getTopoShape(obj, sub.c_str(), true);
|
||||
if (!shape.isNull()) {
|
||||
shapes.push_back(shape);
|
||||
shapeMats.push_back(&res.first->second);
|
||||
}
|
||||
} catch(Base::Exception &e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
e.ReportException();
|
||||
FC_ERR(getFullName() << " failed to obtain shape from "
|
||||
<< obj->getFullName() << '.' << sub);
|
||||
if(errMsg.empty()) {
|
||||
FC_ERR(getFullName() << " failed to obtain shape from "
|
||||
<< obj->getFullName() << '.' << sub);
|
||||
if (errMsg.empty()) {
|
||||
std::ostringstream ss;
|
||||
ss << "Failed to obtain shape " <<
|
||||
obj->getFullName() << '.'
|
||||
obj->getFullName() << '.'
|
||||
<< Data::ComplexGeoData::oldElementName(sub.c_str());
|
||||
errMsg = ss.str();
|
||||
}
|
||||
@@ -636,46 +645,46 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
|
||||
std::string objName;
|
||||
// lambda function for generating matrix cache property
|
||||
auto cacheName = [this,&objName](const App::DocumentObject *obj) {
|
||||
auto cacheName = [this, &objName](const App::DocumentObject* obj) {
|
||||
objName = "Cache_";
|
||||
objName += obj->getNameInDocument();
|
||||
if(obj->getDocument() != getDocument()) {
|
||||
if (obj->getDocument() != getDocument()) {
|
||||
objName += "_";
|
||||
objName += obj->getDocument()->getName();
|
||||
}
|
||||
return objName.c_str();
|
||||
};
|
||||
|
||||
if(!init) {
|
||||
if (!init) {
|
||||
|
||||
if (!errMsg.empty()) {
|
||||
if(!(options & UpdateInit))
|
||||
if (!(options & UpdateInit))
|
||||
FC_THROWM(Base::RuntimeError, errMsg);
|
||||
if(!Shape.getValue().IsNull())
|
||||
if (!Shape.getValue().IsNull())
|
||||
return;
|
||||
}
|
||||
|
||||
// If not forced, only rebuild when there is any change in
|
||||
// transformation matrix
|
||||
if(!forced) {
|
||||
if (!forced) {
|
||||
bool hit = true;
|
||||
for(auto &v : mats) {
|
||||
for (auto& v : mats) {
|
||||
auto prop = Base::freecad_dynamic_cast<App::PropertyMatrix>(
|
||||
getDynamicPropertyByName(cacheName(v.first)));
|
||||
if(!prop || prop->getValue()!=v.second) {
|
||||
getDynamicPropertyByName(cacheName(v.first)));
|
||||
if (!prop || prop->getValue() != v.second) {
|
||||
hit = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(hit)
|
||||
if (hit)
|
||||
return;
|
||||
}
|
||||
|
||||
if(shapes.size()==1 && !Relative.getValue())
|
||||
|
||||
if (shapes.size() == 1 && !Relative.getValue())
|
||||
shapes.back().setPlacement(Base::Placement());
|
||||
else {
|
||||
for(size_t i=0;i<shapes.size();++i) {
|
||||
auto &shape = shapes[i];
|
||||
for (size_t i = 0; i < shapes.size(); ++i) {
|
||||
auto& shape = shapes[i];
|
||||
shape = shape.makeTransform(*shapeMats[i]);
|
||||
// if(shape.Hasher
|
||||
// && shape.getElementMapSize()
|
||||
@@ -687,7 +696,7 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
}
|
||||
}
|
||||
|
||||
if(shapes.empty()) {
|
||||
if (shapes.empty()) {
|
||||
// Shape.resetElementMapVersion();
|
||||
return;
|
||||
}
|
||||
@@ -695,50 +704,53 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
result.makeCompound(shapes);
|
||||
|
||||
bool fused = false;
|
||||
if(Fuse.getValue()) {
|
||||
if (Fuse.getValue()) {
|
||||
// If the compound has solid, fuse them together, and ignore other type of
|
||||
// shapes
|
||||
std::vector<TopoDS_Shape> solids;
|
||||
Part::TopoShape solid;
|
||||
for(auto &s : result.getSubTopoShapes(TopAbs_SOLID)) {
|
||||
if(solid.isNull())
|
||||
for (auto& s : result.getSubTopoShapes(TopAbs_SOLID)) {
|
||||
if (solid.isNull())
|
||||
solid = s;
|
||||
else
|
||||
else
|
||||
solids.push_back(s.getShape());
|
||||
}
|
||||
if (!solids.empty()) {
|
||||
result = solid.fuse(solids);
|
||||
fused = true;
|
||||
} else if (!solid.isNull()) {
|
||||
}
|
||||
else if (!solid.isNull()) {
|
||||
// wrap the single solid in compound to keep its placement
|
||||
result.makeCompound({solid});
|
||||
result.makeCompound({ solid });
|
||||
fused = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!fused && result.hasSubShape(TopAbs_EDGE)
|
||||
&& Offset.getValue() != 0.0){
|
||||
&& Offset.getValue() != 0.0) {
|
||||
try {
|
||||
result = result.makeOffset2D(Offset.getValue(),
|
||||
OffsetJoinType.getValue(),
|
||||
OffsetFill.getValue(),
|
||||
OffsetOpenResult.getValue(),
|
||||
OffsetIntersection.getValue());
|
||||
}catch(...){
|
||||
}
|
||||
catch (...) {
|
||||
std::ostringstream msg;
|
||||
msg << Label.getValue() << ": failed to make 2D offset" << std::endl;
|
||||
Base::Console().Error(msg.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if(!fused && MakeFace.getValue()
|
||||
&& !result.hasSubShape(TopAbs_FACE)
|
||||
&& result.hasSubShape(TopAbs_EDGE))
|
||||
if (!fused && MakeFace.getValue()
|
||||
&& !result.hasSubShape(TopAbs_FACE)
|
||||
&& result.hasSubShape(TopAbs_EDGE))
|
||||
{
|
||||
result = result.makeWires();
|
||||
try {
|
||||
result = result.makeFace(nullptr);
|
||||
}catch(...){}
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
if (Refine.getValue())
|
||||
@@ -750,39 +762,41 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
|
||||
// collect transformation matrix cache entries
|
||||
std::unordered_set<std::string> caches;
|
||||
for(const auto &name : getDynamicPropertyNames()) {
|
||||
if(boost::starts_with(name,"Cache_"))
|
||||
for (const auto& name : getDynamicPropertyNames()) {
|
||||
if (boost::starts_with(name, "Cache_"))
|
||||
caches.emplace(name);
|
||||
}
|
||||
|
||||
// update transformation matrix cache
|
||||
for(auto &v : mats) {
|
||||
const char *name = cacheName(v.first);
|
||||
for (auto& v : mats) {
|
||||
const char* name = cacheName(v.first);
|
||||
auto prop = getDynamicPropertyByName(name);
|
||||
if(!prop || !prop->isDerivedFrom(App::PropertyMatrix::getClassTypeId())) {
|
||||
if(prop)
|
||||
if (!prop || !prop->isDerivedFrom(App::PropertyMatrix::getClassTypeId())) {
|
||||
if (prop)
|
||||
removeDynamicProperty(name);
|
||||
prop = addDynamicProperty("App::PropertyMatrix",name,"Cache",nullptr,0,false,true);
|
||||
prop = addDynamicProperty("App::PropertyMatrix", name, "Cache", nullptr, 0, false, true);
|
||||
}
|
||||
caches.erase(name);
|
||||
static_cast<App::PropertyMatrix*>(prop)->setValue(v.second);
|
||||
}
|
||||
|
||||
// remove any non-used cache entries.
|
||||
for(const auto &name : caches) {
|
||||
for (const auto& name : caches) {
|
||||
try {
|
||||
removeDynamicProperty(name.c_str());
|
||||
} catch(...) {}
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
void SubShapeBinder::slotRecomputedObject(const App::DocumentObject& Obj) {
|
||||
if(Context.getValue() == &Obj
|
||||
if (Context.getValue() == &Obj
|
||||
&& !this->testStatus(App::ObjectStatus::Recompute2))
|
||||
{
|
||||
try {
|
||||
update();
|
||||
} catch (Base::Exception &e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
@@ -792,66 +806,72 @@ App::DocumentObjectExecReturn* SubShapeBinder::execute(void) {
|
||||
|
||||
setupCopyOnChange();
|
||||
|
||||
if(BindMode.getValue()==0)
|
||||
if (BindMode.getValue() == 0)
|
||||
update(UpdateForced);
|
||||
|
||||
return inherited::execute();
|
||||
}
|
||||
|
||||
void SubShapeBinder::onDocumentRestored() {
|
||||
if(_Version.getValue()<2)
|
||||
if (_Version.getValue() < 2)
|
||||
update(UpdateInit);
|
||||
inherited::onDocumentRestored();
|
||||
}
|
||||
|
||||
void SubShapeBinder::onChanged(const App::Property *prop) {
|
||||
if(prop == &Context || prop == &Relative) {
|
||||
if(!Context.getValue() || !Relative.getValue()) {
|
||||
void SubShapeBinder::onChanged(const App::Property* prop) {
|
||||
if (prop == &Context || prop == &Relative) {
|
||||
if (!Context.getValue() || !Relative.getValue()) {
|
||||
connRecomputedObj.disconnect();
|
||||
} else if(contextDoc != Context.getValue()->getDocument()
|
||||
|| !connRecomputedObj.connected())
|
||||
}
|
||||
else if (contextDoc != Context.getValue()->getDocument()
|
||||
|| !connRecomputedObj.connected())
|
||||
{
|
||||
contextDoc = Context.getValue()->getDocument();
|
||||
connRecomputedObj = contextDoc->signalRecomputedObject.connect(
|
||||
boost::bind(&SubShapeBinder::slotRecomputedObject, this, bp::_1));
|
||||
boost::bind(&SubShapeBinder::slotRecomputedObject, this, bp::_1));
|
||||
}
|
||||
}else if(!isRestoring()) {
|
||||
if(prop == &Support) {
|
||||
}
|
||||
else if (!isRestoring()) {
|
||||
if (prop == &Support) {
|
||||
clearCopiedObjects();
|
||||
setupCopyOnChange();
|
||||
if (!Support.getSubListValues().empty()) {
|
||||
update();
|
||||
if(BindMode.getValue() == 2)
|
||||
update();
|
||||
if (BindMode.getValue() == 2)
|
||||
Support.setValue(nullptr);
|
||||
}
|
||||
}else if(prop == &BindCopyOnChange) {
|
||||
}
|
||||
else if (prop == &BindCopyOnChange) {
|
||||
setupCopyOnChange();
|
||||
}else if(prop == &BindMode) {
|
||||
if(BindMode.getValue() == 2)
|
||||
Support.setValue(nullptr);
|
||||
else if(BindMode.getValue() == 0)
|
||||
update();
|
||||
checkPropertyStatus();
|
||||
}else if(prop == &PartialLoad) {
|
||||
checkPropertyStatus();
|
||||
}else if(prop && !prop->testStatus(App::Property::User3))
|
||||
}
|
||||
else if (prop == &BindMode) {
|
||||
if (BindMode.getValue() == 2)
|
||||
Support.setValue(nullptr);
|
||||
else if (BindMode.getValue() == 0)
|
||||
update();
|
||||
checkPropertyStatus();
|
||||
}
|
||||
else if (prop == &PartialLoad) {
|
||||
checkPropertyStatus();
|
||||
}
|
||||
else if (prop && !prop->testStatus(App::Property::User3))
|
||||
checkCopyOnChange(*prop);
|
||||
}
|
||||
inherited::onChanged(prop);
|
||||
}
|
||||
|
||||
void SubShapeBinder::checkCopyOnChange(const App::Property &prop) {
|
||||
if(BindCopyOnChange.getValue()!=1
|
||||
|| getDocument()->isPerformingTransaction()
|
||||
|| !App::LinkBaseExtension::isCopyOnChangeProperty(this,prop)
|
||||
|| Support.getSubListValues().size()!=1)
|
||||
void SubShapeBinder::checkCopyOnChange(const App::Property& prop) {
|
||||
if (BindCopyOnChange.getValue() != 1
|
||||
|| getDocument()->isPerformingTransaction()
|
||||
|| !App::LinkBaseExtension::isCopyOnChangeProperty(this, prop)
|
||||
|| Support.getSubListValues().size() != 1)
|
||||
return;
|
||||
|
||||
auto linked = Support.getSubListValues().front().getValue();
|
||||
if(!linked)
|
||||
if (!linked)
|
||||
return;
|
||||
auto linkedProp = linked->getPropertyByName(prop.getName());
|
||||
if(linkedProp && linkedProp->getTypeId()==prop.getTypeId() && !linkedProp->isSame(prop))
|
||||
if (linkedProp && linkedProp->getTypeId() == prop.getTypeId() && !linkedProp->isSame(prop))
|
||||
BindCopyOnChange.setValue(2);
|
||||
}
|
||||
|
||||
@@ -865,10 +885,10 @@ void SubShapeBinder::checkPropertyStatus() {
|
||||
// Shape.setStatus(App::Property::Transient, !PartialLoad.getValue() && BindMode.getValue()==0);
|
||||
}
|
||||
|
||||
void SubShapeBinder::setLinks(std::map<App::DocumentObject *, std::vector<std::string> >&&values, bool reset)
|
||||
void SubShapeBinder::setLinks(std::map<App::DocumentObject*, std::vector<std::string> >&& values, bool reset)
|
||||
{
|
||||
if(values.empty()) {
|
||||
if(reset) {
|
||||
if (values.empty()) {
|
||||
if (reset) {
|
||||
Support.setValue(nullptr);
|
||||
Shape.setValue(Part::TopoShape());
|
||||
}
|
||||
@@ -877,92 +897,97 @@ void SubShapeBinder::setLinks(std::map<App::DocumentObject *, std::vector<std::s
|
||||
auto inSet = getInListEx(true);
|
||||
inSet.insert(this);
|
||||
|
||||
for(auto &v : values) {
|
||||
if(!v.first || !v.first->getNameInDocument())
|
||||
FC_THROWM(Base::ValueError,"Invalid document object");
|
||||
if(inSet.find(v.first)!=inSet.end())
|
||||
for (auto& v : values) {
|
||||
if (!v.first || !v.first->getNameInDocument())
|
||||
FC_THROWM(Base::ValueError, "Invalid document object");
|
||||
if (inSet.find(v.first) != inSet.end())
|
||||
FC_THROWM(Base::ValueError, "Cyclic reference to " << v.first->getFullName());
|
||||
|
||||
if(v.second.empty()) {
|
||||
if (v.second.empty()) {
|
||||
v.second.push_back("");
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::string> wholeSubs;
|
||||
for(auto &sub : v.second) {
|
||||
if(sub.empty()) {
|
||||
for (auto& sub : v.second) {
|
||||
if (sub.empty()) {
|
||||
wholeSubs.clear();
|
||||
v.second.resize(1);
|
||||
v.second[0].clear();
|
||||
break;
|
||||
}else if(sub[sub.size()-1] == '.')
|
||||
}
|
||||
else if (sub[sub.size() - 1] == '.')
|
||||
wholeSubs.push_back(sub);
|
||||
}
|
||||
for(auto &whole : wholeSubs) {
|
||||
for(auto it=v.second.begin();it!=v.second.end();) {
|
||||
auto &sub = *it;
|
||||
if(!boost::starts_with(sub,whole) || sub.size()==whole.size())
|
||||
for (auto& whole : wholeSubs) {
|
||||
for (auto it = v.second.begin(); it != v.second.end();) {
|
||||
auto& sub = *it;
|
||||
if (!boost::starts_with(sub, whole) || sub.size() == whole.size())
|
||||
++it;
|
||||
else {
|
||||
FC_LOG("Remove subname " << sub <<" because of whole selection " << whole);
|
||||
FC_LOG("Remove subname " << sub << " because of whole selection " << whole);
|
||||
it = v.second.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!reset) {
|
||||
for(auto &link : Support.getSubListValues()) {
|
||||
if (!reset) {
|
||||
for (auto& link : Support.getSubListValues()) {
|
||||
auto subs = link.getSubValues();
|
||||
auto &s = values[link.getValue()];
|
||||
if(s.empty()) {
|
||||
auto& s = values[link.getValue()];
|
||||
if (s.empty()) {
|
||||
s = std::move(subs);
|
||||
continue;
|
||||
}else if(subs.empty() || s[0].empty())
|
||||
}
|
||||
else if (subs.empty() || s[0].empty())
|
||||
continue;
|
||||
|
||||
for(auto &sub : s) {
|
||||
for(auto it=subs.begin();it!=subs.end();) {
|
||||
if(sub[sub.size()-1] == '.') {
|
||||
if(boost::starts_with(*it,sub)) {
|
||||
FC_LOG("Remove subname " << *it <<" because of whole selection " << sub);
|
||||
for (auto& sub : s) {
|
||||
for (auto it = subs.begin(); it != subs.end();) {
|
||||
if (sub[sub.size() - 1] == '.') {
|
||||
if (boost::starts_with(*it, sub)) {
|
||||
FC_LOG("Remove subname " << *it << " because of whole selection " << sub);
|
||||
it = subs.erase(it);
|
||||
} else
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}else if(it->empty()
|
||||
|| (it->back()=='.' && boost::starts_with(sub,*it)))
|
||||
}
|
||||
else if (it->empty()
|
||||
|| (it->back() == '.' && boost::starts_with(sub, *it)))
|
||||
{
|
||||
FC_LOG("Remove whole subname " << *it <<" because of " << sub);
|
||||
FC_LOG("Remove whole subname " << *it << " because of " << sub);
|
||||
it = subs.erase(it);
|
||||
} else
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
subs.insert(subs.end(),s.begin(),s.end());
|
||||
subs.insert(subs.end(), s.begin(), s.end());
|
||||
s = std::move(subs);
|
||||
}
|
||||
}
|
||||
Support.setValues(std::move(values));
|
||||
}
|
||||
|
||||
|
||||
void SubShapeBinder::handleChangedPropertyType(
|
||||
Base::XMLReader &reader, const char * TypeName, App::Property * prop)
|
||||
Base::XMLReader& reader, const char* TypeName, App::Property* prop)
|
||||
{
|
||||
if(prop == &Support) {
|
||||
Support.upgrade(reader,TypeName);
|
||||
}
|
||||
else {
|
||||
inherited::handleChangedPropertyType(reader,TypeName,prop);
|
||||
}
|
||||
if (prop == &Support) {
|
||||
Support.upgrade(reader, TypeName);
|
||||
}
|
||||
else {
|
||||
inherited::handleChangedPropertyType(reader, TypeName, prop);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace App {
|
||||
PROPERTY_SOURCE_TEMPLATE(PartDesign::SubShapeBinderPython, PartDesign::SubShapeBinder)
|
||||
template<> const char* PartDesign::SubShapeBinderPython::getViewProviderName(void) const {
|
||||
return "PartDesignGui::ViewProviderSubShapeBinderPython";
|
||||
}
|
||||
template class PartDesignExport FeaturePythonT<PartDesign::SubShapeBinder>;
|
||||
PROPERTY_SOURCE_TEMPLATE(PartDesign::SubShapeBinderPython, PartDesign::SubShapeBinder)
|
||||
template<> const char* PartDesign::SubShapeBinderPython::getViewProviderName(void) const {
|
||||
return "PartDesignGui::ViewProviderSubShapeBinderPython";
|
||||
}
|
||||
template class PartDesignExport FeaturePythonT<PartDesign::SubShapeBinder>;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ using namespace Gui;
|
||||
|
||||
// TODO Review and cleanup the file (2015-09-11, Fat-Zer)
|
||||
|
||||
TaskShapeBinder::TaskShapeBinder(ViewProviderShapeBinder *view, bool /*newObj*/, QWidget *parent)
|
||||
TaskShapeBinder::TaskShapeBinder(ViewProviderShapeBinder* view, bool /*newObj*/, QWidget* parent)
|
||||
: Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("PartDesign_ShapeBinder"),
|
||||
tr("Datum shape parameters"), true, parent)
|
||||
tr("Datum shape parameters"), true, parent)
|
||||
, SelectionObserver(view)
|
||||
, ui(new Ui_TaskShapeBinder)
|
||||
{
|
||||
@@ -66,45 +66,45 @@ TaskShapeBinder::TaskShapeBinder(ViewProviderShapeBinder *view, bool /*newObj*/,
|
||||
QMetaObject::connectSlotsByName(this);
|
||||
|
||||
connect(ui->buttonRefAdd, SIGNAL(toggled(bool)),
|
||||
this, SLOT(onButtonRefAdd(bool)));
|
||||
this, SLOT(onButtonRefAdd(bool)));
|
||||
connect(ui->buttonRefRemove, SIGNAL(toggled(bool)),
|
||||
this, SLOT(onButtonRefRemove(bool)));
|
||||
this, SLOT(onButtonRefRemove(bool)));
|
||||
connect(ui->buttonBase, SIGNAL(toggled(bool)),
|
||||
this, SLOT(onBaseButton(bool)));
|
||||
|
||||
this, SLOT(onBaseButton(bool)));
|
||||
|
||||
this->groupLayout()->addWidget(proxy);
|
||||
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
vp = view;
|
||||
|
||||
|
||||
//add initial values
|
||||
App::GeoFeature* obj = nullptr;
|
||||
std::vector<std::string> subs;
|
||||
|
||||
PartDesign::ShapeBinder::getFilteredReferences(&static_cast<PartDesign::ShapeBinder*>(vp->getObject())->Support, obj, subs);
|
||||
|
||||
if(obj)
|
||||
|
||||
PartDesign::ShapeBinder::getFilteredReferences(&static_cast<PartDesign::ShapeBinder*>(vp->getObject())->Support, obj, subs);
|
||||
|
||||
if (obj)
|
||||
ui->baseEdit->setText(QString::fromUtf8(obj->getNameInDocument()));
|
||||
|
||||
for (auto sub : subs)
|
||||
ui->listWidgetReferences->addItem(QString::fromStdString(sub));
|
||||
|
||||
|
||||
//make sure the user sees all important things: the base feature to select edges and the
|
||||
//spine/auxiliary spine they already selected
|
||||
if(obj) {
|
||||
if (obj) {
|
||||
auto* svp = doc->getViewProvider(obj);
|
||||
if(svp) {
|
||||
if (svp) {
|
||||
supportShow = svp->isShow();
|
||||
svp->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void TaskShapeBinder::updateUI()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TaskShapeBinder::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
@@ -116,26 +116,27 @@ void TaskShapeBinder::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
if (referenceSelected(msg)) {
|
||||
if (selectionMode == refAdd) {
|
||||
QString sub = QString::fromStdString(msg.pSubName);
|
||||
if(!sub.isEmpty())
|
||||
if (!sub.isEmpty())
|
||||
ui->listWidgetReferences->addItem(QString::fromStdString(msg.pSubName));
|
||||
|
||||
|
||||
ui->baseEdit->setText(QString::fromStdString(msg.pObjectName));
|
||||
}
|
||||
else if (selectionMode == refRemove) {
|
||||
QString sub = QString::fromStdString(msg.pSubName);
|
||||
if(!sub.isEmpty())
|
||||
if (!sub.isEmpty())
|
||||
removeFromListWidget(ui->listWidgetReferences, QString::fromUtf8(msg.pSubName));
|
||||
else {
|
||||
ui->baseEdit->clear();
|
||||
}
|
||||
} else if(selectionMode == refObjAdd) {
|
||||
}
|
||||
}
|
||||
else if (selectionMode == refObjAdd) {
|
||||
ui->listWidgetReferences->clear();
|
||||
ui->baseEdit->setText(QString::fromUtf8(msg.pObjectName));
|
||||
}
|
||||
clearButtons();
|
||||
static_cast<ViewProviderShapeBinder*>(vp)->highlightReferences(false, false);
|
||||
vp->getObject()->getDocument()->recomputeFeature(vp->getObject());
|
||||
}
|
||||
}
|
||||
clearButtons();
|
||||
exitSelectionMode();
|
||||
}
|
||||
@@ -144,9 +145,9 @@ void TaskShapeBinder::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
TaskShapeBinder::~TaskShapeBinder()
|
||||
{/*
|
||||
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(vp->getObject());
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
|
||||
//make sure the user sees all important things: the base feature to select edges and the
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
|
||||
//make sure the user sees all important things: the base feature to select edges and the
|
||||
//spine/auxiliary spine they already selected
|
||||
if(pipe->BaseFeature.getValue())
|
||||
doc->getViewProvider(pipe->BaseFeature.getValue())->hide();
|
||||
@@ -159,12 +160,12 @@ TaskShapeBinder::~TaskShapeBinder()
|
||||
*/
|
||||
}
|
||||
|
||||
void TaskShapeBinder::changeEvent(QEvent *)
|
||||
void TaskShapeBinder::changeEvent(QEvent*)
|
||||
{
|
||||
}
|
||||
|
||||
void TaskShapeBinder::onButtonRefAdd(bool checked) {
|
||||
|
||||
|
||||
if (checked) {
|
||||
//clearButtons(refAdd);
|
||||
//hideObject();
|
||||
@@ -179,7 +180,7 @@ void TaskShapeBinder::onButtonRefRemove(bool checked) {
|
||||
if (checked) {
|
||||
//clearButtons(refRemove);
|
||||
//hideObject();
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().clearSelection();
|
||||
selectionMode = refRemove;
|
||||
vp->highlightReferences(true, false);
|
||||
}
|
||||
@@ -190,7 +191,7 @@ void TaskShapeBinder::onBaseButton(bool checked) {
|
||||
if (checked) {
|
||||
//clearButtons(refRemove);
|
||||
//hideObject();
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().clearSelection();
|
||||
selectionMode = refObjAdd;
|
||||
//DressUpView->highlightReferences(true);
|
||||
}
|
||||
@@ -208,19 +209,19 @@ void TaskShapeBinder::removeFromListWidget(QListWidget* widget, QString itemstr)
|
||||
}
|
||||
|
||||
bool TaskShapeBinder::referenceSelected(const SelectionChanges& msg) const {
|
||||
|
||||
|
||||
if ((msg.Type == Gui::SelectionChanges::AddSelection) && (
|
||||
(selectionMode == refAdd) || (selectionMode == refRemove)
|
||||
|| (selectionMode == refObjAdd))) {
|
||||
(selectionMode == refAdd) || (selectionMode == refRemove)
|
||||
|| (selectionMode == refObjAdd))) {
|
||||
|
||||
if (strcmp(msg.pDocName, vp->getObject()->getDocument()->getName()) != 0)
|
||||
return false;
|
||||
|
||||
// not allowed to reference ourself
|
||||
const char* fname = vp->getObject()->getNameInDocument();
|
||||
const char* fname = vp->getObject()->getNameInDocument();
|
||||
if (strcmp(msg.pObjectName, fname) == 0)
|
||||
return false;
|
||||
|
||||
|
||||
//change the references
|
||||
std::string subName(msg.pSubName);
|
||||
|
||||
@@ -245,7 +246,7 @@ bool TaskShapeBinder::referenceSelected(const SelectionChanges& msg) const {
|
||||
obj = selectedObj;
|
||||
}
|
||||
|
||||
if(selectionMode != refObjAdd) {
|
||||
if (selectionMode != refObjAdd) {
|
||||
// ensure the new selected subref belongs to the same object
|
||||
if (strcmp(msg.pObjectName, obj->getNameInDocument()) != 0)
|
||||
return false;
|
||||
@@ -257,7 +258,8 @@ bool TaskShapeBinder::referenceSelected(const SelectionChanges& msg) const {
|
||||
refs.push_back(subName);
|
||||
else
|
||||
return false; // duplicate selection
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (f != refs.end())
|
||||
refs.erase(f);
|
||||
else
|
||||
@@ -269,7 +271,7 @@ bool TaskShapeBinder::referenceSelected(const SelectionChanges& msg) const {
|
||||
refs.clear();
|
||||
obj = selectedObj;
|
||||
}
|
||||
|
||||
|
||||
static_cast<PartDesign::ShapeBinder*>(vp->getObject())->Support.setValue(obj, refs);
|
||||
|
||||
return true;
|
||||
@@ -296,11 +298,11 @@ void TaskShapeBinder::exitSelectionMode() {
|
||||
// TaskDialog
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TaskDlgShapeBinder::TaskDlgShapeBinder(ViewProviderShapeBinder *view, bool newObj)
|
||||
: Gui::TaskView::TaskDialog()
|
||||
TaskDlgShapeBinder::TaskDlgShapeBinder(ViewProviderShapeBinder* view, bool newObj)
|
||||
: Gui::TaskView::TaskDialog()
|
||||
{
|
||||
assert(view);
|
||||
parameter = new TaskShapeBinder(view, newObj);
|
||||
parameter = new TaskShapeBinder(view, newObj);
|
||||
vp = view;
|
||||
|
||||
Content.push_back(parameter);
|
||||
@@ -319,10 +321,10 @@ bool TaskDlgShapeBinder::accept()
|
||||
std::string name = vp->getObject()->getNameInDocument();
|
||||
|
||||
try {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
if (!vp->getObject()->isValid())
|
||||
throw Base::RuntimeError(vp->getObject()->getStatusString());
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
|
||||
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()");
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
@@ -335,11 +337,11 @@ bool TaskDlgShapeBinder::accept()
|
||||
|
||||
bool TaskDlgShapeBinder::reject()
|
||||
{
|
||||
// roll back the done things
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()");
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
return true;
|
||||
// roll back the done things
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()");
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "moc_TaskShapeBinder.cpp"
|
||||
|
||||
@@ -67,10 +67,10 @@ ViewProviderShapeBinder::ViewProviderShapeBinder()
|
||||
|
||||
//get the datum coloring scheme
|
||||
// set default color for datums (golden yellow with 60% transparency)
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath (
|
||||
"User parameter:BaseApp/Preferences/Mod/PartDesign");
|
||||
unsigned long shcol = hGrp->GetUnsigned ( "DefaultDatumColor", 0xFFD70099 );
|
||||
App::Color col ( (uint32_t) shcol );
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/PartDesign");
|
||||
unsigned long shcol = hGrp->GetUnsigned("DefaultDatumColor", 0xFFD70099);
|
||||
App::Color col((uint32_t)shcol);
|
||||
|
||||
ShapeColor.setValue(col);
|
||||
LineColor.setValue(col);
|
||||
@@ -91,8 +91,8 @@ bool ViewProviderShapeBinder::setEdit(int ModNum) {
|
||||
// When double-clicking on the item for this pad the
|
||||
// object unsets and sets its edit mode without closing
|
||||
// the task panel
|
||||
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
|
||||
TaskDlgShapeBinder *sbDlg = qobject_cast<TaskDlgShapeBinder*>(dlg);
|
||||
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
|
||||
TaskDlgShapeBinder* sbDlg = qobject_cast<TaskDlgShapeBinder*>(dlg);
|
||||
if (dlg && !sbDlg) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
|
||||
@@ -114,7 +114,7 @@ bool ViewProviderShapeBinder::setEdit(int ModNum) {
|
||||
if (sbDlg)
|
||||
Gui::Control().showDialog(sbDlg);
|
||||
else
|
||||
Gui::Control().showDialog(new TaskDlgShapeBinder(this,ModNum == 1));
|
||||
Gui::Control().showDialog(new TaskDlgShapeBinder(this, ModNum == 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -143,11 +143,11 @@ void ViewProviderShapeBinder::highlightReferences(const bool on, bool /*auxiliar
|
||||
return;
|
||||
|
||||
PartGui::ViewProviderPart* svp = dynamic_cast<PartGui::ViewProviderPart*>(
|
||||
Gui::Application::Instance->getViewProvider(obj));
|
||||
Gui::Application::Instance->getViewProvider(obj));
|
||||
if (svp == nullptr) return;
|
||||
|
||||
if (on) {
|
||||
if (!subs.empty() && originalLineColors.empty()) {
|
||||
if (!subs.empty() && originalLineColors.empty()) {
|
||||
TopTools_IndexedMapOfShape eMap;
|
||||
TopExp::MapShapes(static_cast<Part::Feature*>(obj)->Shape.getValue(), TopAbs_EDGE, eMap);
|
||||
originalLineColors = svp->LineColorArray.getValues();
|
||||
@@ -161,23 +161,24 @@ void ViewProviderShapeBinder::highlightReferences(const bool on, bool /*auxiliar
|
||||
|
||||
for (std::string e : subs) {
|
||||
// Note: stoi may throw, but it strictly shouldn't happen
|
||||
if(e.compare(0, 4, "Edge") == 0) {
|
||||
if (e.compare(0, 4, "Edge") == 0) {
|
||||
int idx = std::stoi(e.substr(4)) - 1;
|
||||
assert ( idx>=0 );
|
||||
if ( idx < (ssize_t) lcolors.size() )
|
||||
lcolors[idx] = App::Color(1.0,0.0,1.0); // magenta
|
||||
assert(idx >= 0);
|
||||
if (idx < (ssize_t)lcolors.size())
|
||||
lcolors[idx] = App::Color(1.0, 0.0, 1.0); // magenta
|
||||
}
|
||||
else if(e.compare(0, 4, "Face") == 0) {
|
||||
else if (e.compare(0, 4, "Face") == 0) {
|
||||
int idx = std::stoi(e.substr(4)) - 1;
|
||||
assert ( idx>=0 );
|
||||
if ( idx < (ssize_t) fcolors.size() )
|
||||
fcolors[idx] = App::Color(1.0,0.0,1.0); // magenta
|
||||
assert(idx >= 0);
|
||||
if (idx < (ssize_t)fcolors.size())
|
||||
fcolors[idx] = App::Color(1.0, 0.0, 1.0); // magenta
|
||||
}
|
||||
}
|
||||
svp->LineColorArray.setValues(lcolors);
|
||||
svp->DiffuseColor.setValues(fcolors);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!subs.empty() && !originalLineColors.empty()) {
|
||||
svp->LineColorArray.setValues(originalLineColors);
|
||||
originalLineColors.clear();
|
||||
@@ -193,7 +194,7 @@ void ViewProviderShapeBinder::setupContextMenu(QMenu* menu, QObject* receiver, c
|
||||
Q_UNUSED(receiver)
|
||||
Q_UNUSED(member)
|
||||
|
||||
QAction* act;
|
||||
QAction* act;
|
||||
act = menu->addAction(QObject::tr("Edit shape binder"));
|
||||
act->setData(QVariant((int)ViewProvider::Default));
|
||||
|
||||
@@ -211,37 +212,38 @@ void ViewProviderShapeBinder::setupContextMenu(QMenu* menu, QObject* receiver, c
|
||||
|
||||
//=====================================================================================
|
||||
|
||||
PROPERTY_SOURCE(PartDesignGui::ViewProviderSubShapeBinder,PartGui::ViewProviderPart)
|
||||
PROPERTY_SOURCE(PartDesignGui::ViewProviderSubShapeBinder, PartGui::ViewProviderPart)
|
||||
|
||||
ViewProviderSubShapeBinder::ViewProviderSubShapeBinder() {
|
||||
sPixmap = "PartDesign_SubShapeBinder.svg";
|
||||
|
||||
ADD_PROPERTY_TYPE(UseBinderStyle, (false), "",(App::PropertyType)(App::Prop_None), "");
|
||||
ADD_PROPERTY_TYPE(UseBinderStyle, (false), "", (App::PropertyType)(App::Prop_None), "");
|
||||
}
|
||||
|
||||
void ViewProviderSubShapeBinder::attach(App::DocumentObject *obj) {
|
||||
void ViewProviderSubShapeBinder::attach(App::DocumentObject* obj) {
|
||||
|
||||
UseBinderStyle.setValue(boost::istarts_with(obj->getNameInDocument(),"binder"));
|
||||
UseBinderStyle.setValue(boost::istarts_with(obj->getNameInDocument(), "binder"));
|
||||
ViewProviderPart::attach(obj);
|
||||
}
|
||||
|
||||
void ViewProviderSubShapeBinder::onChanged(const App::Property *prop) {
|
||||
if(prop == &UseBinderStyle
|
||||
&& (!getObject() || !getObject()->isRestoring()))
|
||||
void ViewProviderSubShapeBinder::onChanged(const App::Property* prop) {
|
||||
if (prop == &UseBinderStyle
|
||||
&& (!getObject() || !getObject()->isRestoring()))
|
||||
{
|
||||
App::Color shapeColor,lineColor,pointColor;
|
||||
App::Color shapeColor, lineColor, pointColor;
|
||||
int transparency, linewidth;
|
||||
if(UseBinderStyle.getValue()) {
|
||||
if (UseBinderStyle.getValue()) {
|
||||
//get the datum coloring scheme
|
||||
// set default color for datums (golden yellow with 60% transparency)
|
||||
static ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath (
|
||||
"User parameter:BaseApp/Preferences/Mod/PartDesign");
|
||||
shapeColor.setPackedValue(hGrp->GetUnsigned ( "DefaultDatumColor", 0xFFD70099 ));
|
||||
static ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/PartDesign");
|
||||
shapeColor.setPackedValue(hGrp->GetUnsigned("DefaultDatumColor", 0xFFD70099));
|
||||
lineColor = shapeColor;
|
||||
pointColor = shapeColor;
|
||||
transparency = 60;
|
||||
linewidth = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
shapeColor.setPackedValue(Gui::ViewParams::instance()->getDefaultShapeColor());
|
||||
lineColor.setPackedValue(Gui::ViewParams::instance()->getDefaultShapeLineColor());
|
||||
pointColor = lineColor;
|
||||
@@ -258,35 +260,36 @@ void ViewProviderSubShapeBinder::onChanged(const App::Property *prop) {
|
||||
ViewProviderPart::onChanged(prop);
|
||||
}
|
||||
|
||||
bool ViewProviderSubShapeBinder::canDropObjectEx(App::DocumentObject *,
|
||||
App::DocumentObject *, const char *, const std::vector<std::string> &) const
|
||||
bool ViewProviderSubShapeBinder::canDropObjectEx(App::DocumentObject*,
|
||||
App::DocumentObject*, const char*, const std::vector<std::string>&) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ViewProviderSubShapeBinder::dropObjectEx(App::DocumentObject *obj, App::DocumentObject *owner,
|
||||
const char *subname, const std::vector<std::string> &elements)
|
||||
std::string ViewProviderSubShapeBinder::dropObjectEx(App::DocumentObject* obj, App::DocumentObject* owner,
|
||||
const char* subname, const std::vector<std::string>& elements)
|
||||
{
|
||||
auto self = dynamic_cast<PartDesign::SubShapeBinder*>(getObject());
|
||||
if(!self) return std::string();
|
||||
std::map<App::DocumentObject *, std::vector<std::string> > values;
|
||||
if(!subname) subname = "";
|
||||
if (!self) return std::string();
|
||||
std::map<App::DocumentObject*, std::vector<std::string> > values;
|
||||
if (!subname) subname = "";
|
||||
std::string sub(subname);
|
||||
if(sub.empty())
|
||||
values[owner?owner:obj] = elements;
|
||||
if (sub.empty())
|
||||
values[owner ? owner : obj] = elements;
|
||||
else {
|
||||
std::vector<std::string> subs;
|
||||
if(elements.size()) {
|
||||
if (elements.size()) {
|
||||
subs.reserve(elements.size());
|
||||
for(auto &element : elements)
|
||||
subs.push_back(sub+element);
|
||||
}else
|
||||
for (auto& element : elements)
|
||||
subs.push_back(sub + element);
|
||||
}
|
||||
else
|
||||
subs.push_back(sub);
|
||||
values[owner?owner:obj] = std::move(subs);
|
||||
values[owner ? owner : obj] = std::move(subs);
|
||||
}
|
||||
|
||||
self->setLinks(std::move(values),QApplication::keyboardModifiers()==Qt::ControlModifier);
|
||||
if(self->Relative.getValue())
|
||||
self->setLinks(std::move(values), QApplication::keyboardModifiers() == Qt::ControlModifier);
|
||||
if (self->Relative.getValue())
|
||||
updatePlacement(false);
|
||||
return std::string();
|
||||
}
|
||||
@@ -297,40 +300,40 @@ bool ViewProviderSubShapeBinder::doubleClicked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewProviderSubShapeBinder::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
|
||||
void ViewProviderSubShapeBinder::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
|
||||
{
|
||||
QAction* act;
|
||||
act = menu->addAction(QObject::tr("Synchronize"), receiver, member);
|
||||
act->setData(QVariant((int)Synchronize));
|
||||
act = menu->addAction(QObject::tr("Select bound object"), receiver, member);
|
||||
act->setData(QVariant((int)SelectObject));
|
||||
ViewProviderPart::setupContextMenu(menu,receiver,member);
|
||||
ViewProviderPart::setupContextMenu(menu, receiver, member);
|
||||
}
|
||||
|
||||
bool ViewProviderSubShapeBinder::setEdit(int ModNum) {
|
||||
|
||||
switch(ModNum) {
|
||||
|
||||
switch (ModNum) {
|
||||
case Synchronize:
|
||||
updatePlacement(true);
|
||||
break;
|
||||
case SelectObject: {
|
||||
auto self = dynamic_cast<PartDesign::SubShapeBinder*>(getObject());
|
||||
if(!self || !self->Support.getValue())
|
||||
if (!self || !self->Support.getValue())
|
||||
break;
|
||||
|
||||
Gui::Selection().selStackPush();
|
||||
Gui::Selection().clearSelection();
|
||||
for(auto &link : self->Support.getSubListValues()) {
|
||||
for (auto& link : self->Support.getSubListValues()) {
|
||||
auto obj = link.getValue();
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
if (!obj || !obj->getNameInDocument())
|
||||
continue;
|
||||
const auto &subs = link.getSubValues();
|
||||
if(subs.size())
|
||||
const auto& subs = link.getSubValues();
|
||||
if (subs.size())
|
||||
Gui::Selection().addSelections(obj->getDocument()->getName(),
|
||||
obj->getNameInDocument(),subs);
|
||||
obj->getNameInDocument(), subs);
|
||||
else
|
||||
Gui::Selection().addSelection(obj->getDocument()->getName(),
|
||||
obj->getNameInDocument());
|
||||
obj->getNameInDocument());
|
||||
}
|
||||
Gui::Selection().selStackPush();
|
||||
break;
|
||||
@@ -343,74 +346,78 @@ bool ViewProviderSubShapeBinder::setEdit(int ModNum) {
|
||||
|
||||
void ViewProviderSubShapeBinder::updatePlacement(bool transaction) {
|
||||
auto self = dynamic_cast<PartDesign::SubShapeBinder*>(getObject());
|
||||
if(!self || !self->Support.getValue())
|
||||
if (!self || !self->Support.getValue())
|
||||
return;
|
||||
|
||||
std::vector<Base::Matrix4D> mats;
|
||||
bool relative = self->Relative.getValue();
|
||||
App::DocumentObject *parent = nullptr;
|
||||
App::DocumentObject* parent = nullptr;
|
||||
std::string parentSub;
|
||||
if(relative && self->getParents().size()) {
|
||||
const auto &sel = Gui::Selection().getSelection("",0);
|
||||
if(sel.size()!=1 || !sel[0].pObject ||
|
||||
sel[0].pObject->getSubObject(sel[0].SubName)!=self)
|
||||
if (relative && self->getParents().size()) {
|
||||
const auto& sel = Gui::Selection().getSelection("", 0);
|
||||
if (sel.size() != 1 || !sel[0].pObject ||
|
||||
sel[0].pObject->getSubObject(sel[0].SubName) != self)
|
||||
{
|
||||
FC_WARN("invalid selection");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
parent = sel[0].pObject;
|
||||
parentSub = sel[0].SubName;
|
||||
}
|
||||
}
|
||||
|
||||
if(!transaction) {
|
||||
if(relative)
|
||||
self->Context.setValue(parent,parentSub.c_str());
|
||||
if (!transaction) {
|
||||
if (relative)
|
||||
self->Context.setValue(parent, parentSub.c_str());
|
||||
try {
|
||||
self->update(PartDesign::SubShapeBinder::UpdateForced);
|
||||
} catch (Base::Exception &e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
e.ReportException();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
App::GetApplication().setActiveTransaction("Sync binder");
|
||||
try{
|
||||
if(relative)
|
||||
self->Context.setValue(parent,parentSub.c_str());
|
||||
try {
|
||||
if (relative)
|
||||
self->Context.setValue(parent, parentSub.c_str());
|
||||
self->update(PartDesign::SubShapeBinder::UpdateForced);
|
||||
App::GetApplication().closeActiveTransaction();
|
||||
return;
|
||||
}catch(Base::Exception &e) {
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
e.ReportException();
|
||||
}catch(Standard_Failure &e) {
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
std::ostringstream str;
|
||||
Standard_CString msg = e.GetMessageString();
|
||||
str << typeid(e).name() << " ";
|
||||
if (msg) {str << msg;}
|
||||
else {str << "No OCCT Exception Message";}
|
||||
if (msg) { str << msg; }
|
||||
else { str << "No OCCT Exception Message"; }
|
||||
FC_ERR(str.str());
|
||||
}
|
||||
App::GetApplication().closeActiveTransaction(true);
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> ViewProviderSubShapeBinder::claimChildren(void) const {
|
||||
std::vector<App::DocumentObject *> ret;
|
||||
std::vector<App::DocumentObject*> ret;
|
||||
auto self = Base::freecad_dynamic_cast<PartDesign::SubShapeBinder>(getObject());
|
||||
if(self && self->ClaimChildren.getValue() && self->Support.getValue()) {
|
||||
std::set<App::DocumentObject *> objSet;
|
||||
for(auto &l : self->Support.getSubListValues()) {
|
||||
if (self && self->ClaimChildren.getValue() && self->Support.getValue()) {
|
||||
std::set<App::DocumentObject*> objSet;
|
||||
for (auto& l : self->Support.getSubListValues()) {
|
||||
auto obj = l.getValue();
|
||||
if(!obj)
|
||||
if (!obj)
|
||||
continue;
|
||||
const auto &subs = l.getSubValues();
|
||||
if(subs.empty()) {
|
||||
if(objSet.insert(obj).second)
|
||||
const auto& subs = l.getSubValues();
|
||||
if (subs.empty()) {
|
||||
if (objSet.insert(obj).second)
|
||||
ret.push_back(obj);
|
||||
continue;
|
||||
}
|
||||
for(auto &sub : subs) {
|
||||
for (auto& sub : subs) {
|
||||
auto sobj = obj->getSubObject(sub.c_str());
|
||||
if(sobj && objSet.insert(sobj).second)
|
||||
if (sobj && objSet.insert(sobj).second)
|
||||
ret.push_back(sobj);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user