diff --git a/src/Mod/Assembly/Gui/CMakeLists.txt b/src/Mod/Assembly/Gui/CMakeLists.txt index 4779c12e2..837b78fa9 100644 --- a/src/Mod/Assembly/Gui/CMakeLists.txt +++ b/src/Mod/Assembly/Gui/CMakeLists.txt @@ -40,6 +40,8 @@ SET(AssemblyGuiViewProvider_SRCS ViewProviderPart.h ViewProviderAssembly.cpp ViewProviderAssembly.h + ViewProviderConstraint.cpp + ViewProviderConstraint.h ViewProviderConstraintGroup.cpp ViewProviderConstraintGroup.h ViewProviderConstraintFix.cpp diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraint.cpp b/src/Mod/Assembly/Gui/ViewProviderConstraint.cpp new file mode 100644 index 000000000..d5c49cf62 --- /dev/null +++ b/src/Mod/Assembly/Gui/ViewProviderConstraint.cpp @@ -0,0 +1,343 @@ +/*************************************************************************** + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#include "ViewProviderConstraint.h" +#include "Mod/Assembly/App/Constraint.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace AssemblyGui; + +PROPERTY_SOURCE(AssemblyGui::ViewProviderConstraintInternal, PartGui::ViewProviderPart) + +ViewProviderConstraintInternal::ViewProviderConstraintInternal() +{ + //constraint entiti color + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); + unsigned long scol = hGrp->GetUnsigned("ConstructionColor", 421075455UL); // dark grey (25,25,25) + float r, g, b; + r = ((scol >> 24) & 0xff) / 255.0; + g = ((scol >> 16) & 0xff) / 255.0; + b = ((scol >> 8) & 0xff) / 255.0; + + long unsigned ccol = hGrp->GetUnsigned("FullyConstrainedColor", 421075455UL); + float r2, g2, b2; + r2 = ((ccol >> 24) & 0xff) / 255.0; + g2 = ((ccol >> 16) & 0xff) / 255.0; + b2 = ((ccol >> 8) & 0xff) / 255.0; + + + int lwidth = hGrp->GetInt("DefaultShapeLineWidth", 2) + 1; + App::Material mat; + mat.ambientColor.set(0.2f, 0.2f, 0.2f); + mat.diffuseColor.set(r2, g2, b2); + mat.specularColor.set(0.0f, 0.0f, 0.0f); + mat.emissiveColor.set(0.0f, 0.0f, 0.0f); + mat.shininess = 1.0f; + mat.transparency = 0.5f; + LineMaterial.setValue(mat); + PointMaterial.setValue(mat); + LineColor.setValue(mat.diffuseColor); + PointColor.setValue(mat.diffuseColor); + mat.diffuseColor.set(r, g, b); + DiffuseColor.setValue(mat.diffuseColor); + LineWidth.setValue(lwidth); + PointSize.setValue(lwidth); + + Transparency.setValue(50); +}; + +void ViewProviderConstraintInternal::updateVis(const TopoDS_Shape& shape) +{ + updateVisual(shape); +}; + +void ViewProviderConstraintInternal::updatePlacement(const Base::Placement& p) +{ + float q0 = (float)p.getRotation().getValue()[0]; + float q1 = (float)p.getRotation().getValue()[1]; + float q2 = (float)p.getRotation().getValue()[2]; + float q3 = (float)p.getRotation().getValue()[3]; + float px = (float)p.getPosition().x; + float py = (float)p.getPosition().y; + float pz = (float)p.getPosition().z; + pcTransform->rotation.setValue(q0, q1, q2, q3); + pcTransform->translation.setValue(px, py, pz); + pcTransform->center.setValue(0.0f, 0.0f, 0.0f); +} + +void ViewProviderConstraintInternal::switch_node(bool onoff) +{ + if(onoff) + pcModeSwitch->whichChild = 0; + else + pcModeSwitch->whichChild = -1; +} + + +PROPERTY_SOURCE(AssemblyGui::ViewProviderConstraint, PartGui::ViewProviderPart) + +ViewProviderConstraint::ViewProviderConstraint() +{ + Selectable.setValue(false); + + //constraint entiti color + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); + unsigned long scol = hGrp->GetUnsigned("ConstructionColor", 421075455UL); // dark grey (25,25,25) + float r, g, b; + r = ((scol >> 24) & 0xff) / 255.0; + g = ((scol >> 16) & 0xff) / 255.0; + b = ((scol >> 8) & 0xff) / 255.0; + + long unsigned ccol = hGrp->GetUnsigned("FullyConstrainedColor", 421075455UL); + float r2, g2, b2; + r2 = ((ccol >> 24) & 0xff) / 255.0; + g2 = ((ccol >> 16) & 0xff) / 255.0; + b2 = ((ccol >> 8) & 0xff) / 255.0; + + + int lwidth = hGrp->GetInt("DefaultShapeLineWidth", 2) + 1; + App::Material mat; + mat.ambientColor.set(0.2f, 0.2f, 0.2f); + mat.diffuseColor.set(r2, g2, b2); + mat.specularColor.set(0.0f, 0.0f, 0.0f); + mat.emissiveColor.set(0.0f, 0.0f, 0.0f); + mat.shininess = 1.0f; + mat.transparency = 0.5f; + LineMaterial.setValue(mat); + PointMaterial.setValue(mat); + LineColor.setValue(mat.diffuseColor); + PointColor.setValue(mat.diffuseColor); + mat.diffuseColor.set(r, g, b); + DiffuseColor.setValue(mat.diffuseColor); + LineWidth.setValue(lwidth); + PointSize.setValue(lwidth); + + Transparency.setValue(50); +} + +bool ViewProviderConstraint::isShow() const +{ + return Visibility.getValue(); +} + + +void ViewProviderConstraint::attach(App::DocumentObject* pcFeat) +{ + SoAnnotation* m_anno1 = new SoAnnotation; + SoAnnotation* m_anno2 = new SoAnnotation; + + //call parent attach method for normal processing of one visual path + ViewProviderPart::attach(pcFeat); + //bring a annotation node before the normal view mode (others are not used) + m_anno1->addChild(pcModeSwitch->getChild(0)); + pcModeSwitch->replaceChild(0, m_anno1); + + //now also attach a second visual path to the root for our second constraint element + internal_vp.attach(pcFeat); + pcRoot->addChild(m_anno2); + m_anno2->addChild(internal_vp.getRoot()); + + internal_vp.setDisplayMM("Flat Lines"); +} + + +void ViewProviderConstraint::updateData(const App::Property* prop) +{ + Base::Console().Message("update: %s\n", prop->getName()); + + if(Visibility.getValue() && m_selected) { + + draw(); + } + + Gui::ViewProviderGeometryObject::updateData(prop); + internal_vp.Gui::ViewProviderGeometryObject::updateData(prop); +} + +void ViewProviderConstraint::onChanged(const App::Property* prop) +{ + + Base::Console().Message("changed: %s, selected: %i\n", prop->getName(), m_selected); + + // parent expects the app object to be part::feature, but it isn't. so we have to avoid + // the visability prop as this results in accessing of the part::feature and would crash + if(prop == &Visibility) { + if(Visibility.getValue() && m_selected) { + internal_vp.show(); + draw(); + } + else + internal_vp.hide(); + + ViewProviderGeometryObject::onChanged(prop); + internal_vp.onChGO(prop); + } + else { + ViewProviderPart::onChanged(prop); + internal_vp.onChPa(prop); + } +} + +void ViewProviderConstraint::draw() +{ + + TopoDS_Shape s1 = getConstraintShape(1); + updateVisual(s1); + + TopoDS_Shape s2 = getConstraintShape(2); + internal_vp.updateVis(s2); + + App::DocumentObject* obj1 = dynamic_cast(pcObject)->First.getValue(); + + if(!obj1) + return; + + Assembly::ItemPart* part1 = static_cast(obj1); + + if(!part1) + return; + + //the internal draw algorithm removes all locations. but we have this subshape extracted + //from a complex one, therefore it's translation is not respected in the parts rotation + //and if it gets cut away the geometry will be at wrong position + TopLoc_Location l1 = s1.Location(); + gp_XYZ tr1 = l1.Transformation().TranslationPart(); + Base::Placement p1(Base::Vector3d(tr1.X(), tr1.Y(), tr1.Z()), Base::Rotation()); + p1 = part1->Placement.getValue() * p1; + + float q0 = (float)p1.getRotation().getValue()[0]; + float q1 = (float)p1.getRotation().getValue()[1]; + float q2 = (float)p1.getRotation().getValue()[2]; + float q3 = (float)p1.getRotation().getValue()[3]; + float px = (float)p1.getPosition().x; + float py = (float)p1.getPosition().y; + float pz = (float)p1.getPosition().z; + pcTransform->rotation.setValue(q0, q1, q2, q3); + pcTransform->translation.setValue(px, py, pz); + pcTransform->center.setValue(0.0f, 0.0f, 0.0f); + + //Second part + //*********** + App::DocumentObject* obj2 = dynamic_cast(pcObject)->Second.getValue(); + + if(!obj2) + return; + + //here it's a bit more involved, as the coind tree structure let's the first transform node + //transform the second part too. + Assembly::ItemPart* part2 = static_cast(obj2); + + if(!part2) + return; + + //the internal draw algorithm removes all locations. but we have this subshape extracted + //from a complex one, therefore it's shape internal translation is not respected in the parts rotation + //and if it gets cut away the geometry will be at wrong position + TopLoc_Location l2 = s2.Location(); + gp_XYZ tr2 = l2.Transformation().TranslationPart(); + Base::Placement p2(Base::Vector3d(tr2.X(), tr2.Y(), tr2.Z()), Base::Rotation()); + + p2 = p1.inverse() * (part2->Placement.getValue() * p2); + internal_vp.updatePlacement(p2); +} + +void ViewProviderConstraint::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if(Gui::Selection().isSelected(pcObject) && Visibility.getValue()) { + m_selected = true; + + internal_vp.switch_node(true); + pcModeSwitch->whichChild = 0; + draw(); + } + else { + internal_vp.switch_node(false); + pcModeSwitch->whichChild = -1; + m_selected = false; + } +} + + +TopoDS_Shape ViewProviderConstraint::getConstraintShape(int link) +{ + + if(link == 1) { + //subshape of first link + //********************** + App::DocumentObject* obj1 = dynamic_cast(pcObject)->First.getValue(); + + if(!obj1) + return TopoDS_Shape(); + + Assembly::ItemPart* part1 = static_cast(obj1); + + if(!part1) + return TopoDS_Shape(); + + Part::TopoShape ts; + App::DocumentObject* feature1 = part1->Model.getValue(); + + if(feature1->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + ts = static_cast(feature1)->Shape.getShape(); + } + else return TopoDS_Shape(); + + TopoDS_Shape s1 = ts.getSubShape(dynamic_cast(pcObject)->First.getSubValues()[0].c_str()); + + return s1; + } + else { + //subshape of second link + //********************** + App::DocumentObject* obj2 = dynamic_cast(pcObject)->Second.getValue(); + + if(!obj2) + return TopoDS_Shape(); + + Assembly::ItemPart* part2 = static_cast(obj2); + + if(!part2) + return TopoDS_Shape(); + + Part::TopoShape ts2; + App::DocumentObject* feature2 = part2->Model.getValue(); + + if(feature2->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + ts2 = static_cast(feature2)->Shape.getShape(); + } + else return TopoDS_Shape(); + + TopoDS_Shape s2 = ts2.getSubShape(dynamic_cast(pcObject)->Second.getSubValues()[0].c_str()); + + return s2; + }; +} diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraint.h b/src/Mod/Assembly/Gui/ViewProviderConstraint.h new file mode 100644 index 000000000..83547f8fc --- /dev/null +++ b/src/Mod/Assembly/Gui/ViewProviderConstraint.h @@ -0,0 +1,100 @@ +/*************************************************************************** + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef ASSEMBLYGUI_VIEWPROVIDERCONSTRAINT_H +#define ASSEMBLYGUI_VIEWPROVIDERCONSTRAINT_H + +#include +#include +#include +#include + +namespace AssemblyGui { + +//class for internal use to alllow access to protected functions of view provider part. +class AssemblyGuiExport ViewProviderConstraintInternal : public PartGui::ViewProviderPart { + + PROPERTY_HEADER(AssemblyGui::ViewProviderConstraintInternal); + +public: + ViewProviderConstraintInternal(); + void updateVis(const TopoDS_Shape& shape); + void setDisplayMM(const char* mode) { + setDisplayMaskMode(mode); + }; + void onChGO(const App::Property* prop) { + ViewProviderGeometryObject::onChanged(prop); + }; + void onChPa(const App::Property* prop) { + ViewProviderPart::onChanged(prop); + }; + //update the transformation node with a Placement + void updatePlacement(const Base::Placement& p); + //switch the display mode node on or off + void switch_node(bool onoff); +}; + + +//this class adds highlight functionality to the constraint: when a constraint is selected +//in the tree all used geometries are shown +class AssemblyGuiExport ViewProviderConstraint: public PartGui::ViewProviderPart, + public Gui::SelectionObserver { + + PROPERTY_HEADER(AssemblyGui::ViewProviderConstraint); + +public: + ViewProviderConstraint(); + + //attach needs to be overridden to attach the second viewprovider and to include + //annotation nodes + virtual void attach(App::DocumentObject* pcObj); + + //needs to be overridden as this viewprovider dos not represent a Part::Feature + virtual void updateData(const App::Property*); + //needs to be overridden as this viewprovider dos not represent a Part::Feature + virtual void onChanged(const App::Property* prop); + + //get the shape which is used by the constraint for highlighting + virtual TopoDS_Shape getConstraintShape(int link); + + //needs to be overridden as we use the modeselection node for on and off and not for + //hide and show in the normal way + virtual bool isShow(void) const; + +private: + //we need two seperate visual representations, as both constraint parts have different + //placements. + ViewProviderConstraintInternal internal_vp; + + //update visualisation and placements of the scenegraph + void draw(); + + //watch if something got selected in the tree + virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + + bool m_selected; +}; + +}; + +#endif // VIEWPROVIDERCONSTRAINTFIX_H diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraintAlignment.h b/src/Mod/Assembly/Gui/ViewProviderConstraintAlignment.h index 459206fd5..703937d25 100644 --- a/src/Mod/Assembly/Gui/ViewProviderConstraintAlignment.h +++ b/src/Mod/Assembly/Gui/ViewProviderConstraintAlignment.h @@ -24,20 +24,16 @@ #ifndef ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTAlignment_H #define ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTAlignment_H -#include +#include "ViewProviderConstraint.h" namespace AssemblyGui { -class AssemblyGuiExport ViewProviderConstraintAlignment : public Gui::ViewProviderDocumentObject { +class AssemblyGuiExport ViewProviderConstraintAlignment : public ViewProviderConstraint { PROPERTY_HEADER(AssemblyGui::ViewProviderConstraintAlignment); public: ViewProviderConstraintAlignment(); - - /// checks whether the view provider is visible or not in tree - virtual bool isShow(void) const {return true;}; - }; }; diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraintAngle.h b/src/Mod/Assembly/Gui/ViewProviderConstraintAngle.h index ed1097f4d..51b1e849a 100644 --- a/src/Mod/Assembly/Gui/ViewProviderConstraintAngle.h +++ b/src/Mod/Assembly/Gui/ViewProviderConstraintAngle.h @@ -24,19 +24,17 @@ #ifndef ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTANGLE_H #define ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTANGLE_H -#include +#include "ViewProviderConstraint.h" namespace AssemblyGui { -class AssemblyGuiExport ViewProviderConstraintAngle : public Gui::ViewProviderDocumentObject { +class AssemblyGuiExport ViewProviderConstraintAngle : public ViewProviderConstraint { PROPERTY_HEADER(AssemblyGui::ViewProviderConstraintAngle); public: ViewProviderConstraintAngle(); - /// checks whether the view provider is visible or not in tree - virtual bool isShow(void) const {return true;}; }; }; diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraintCoincidence.h b/src/Mod/Assembly/Gui/ViewProviderConstraintCoincidence.h index dee6ab0a2..e922488d0 100644 --- a/src/Mod/Assembly/Gui/ViewProviderConstraintCoincidence.h +++ b/src/Mod/Assembly/Gui/ViewProviderConstraintCoincidence.h @@ -24,19 +24,17 @@ #ifndef ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTCoincidence_H #define ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTCoincidence_H -#include +#include "ViewProviderConstraint.h" namespace AssemblyGui { -class AssemblyGuiExport ViewProviderConstraintCoincidence : public Gui::ViewProviderDocumentObject { +class AssemblyGuiExport ViewProviderConstraintCoincidence : public ViewProviderConstraint { PROPERTY_HEADER(AssemblyGui::ViewProviderConstraintCoincidence); public: ViewProviderConstraintCoincidence(); - /// checks whether the view provider is visible or not in tree - virtual bool isShow(void) const {return true;}; }; }; diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraintDistance.h b/src/Mod/Assembly/Gui/ViewProviderConstraintDistance.h index 9fbff5ba2..574158da1 100644 --- a/src/Mod/Assembly/Gui/ViewProviderConstraintDistance.h +++ b/src/Mod/Assembly/Gui/ViewProviderConstraintDistance.h @@ -25,18 +25,17 @@ #define ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTDISTANCE_H #include +#include "ViewProviderConstraint.h" namespace AssemblyGui { -class AssemblyGuiExport ViewProviderConstraintDistance : public Gui::ViewProviderDocumentObject { +class AssemblyGuiExport ViewProviderConstraintDistance : public ViewProviderConstraint { PROPERTY_HEADER(AssemblyGui::ViewProviderConstraintDistance); public: ViewProviderConstraintDistance(); - /// checks whether the view provider is visible or not in tree - virtual bool isShow(void) const {return true;}; }; }; diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraintFix.cpp b/src/Mod/Assembly/Gui/ViewProviderConstraintFix.cpp index f3f9d22ef..5c673ac9f 100644 --- a/src/Mod/Assembly/Gui/ViewProviderConstraintFix.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderConstraintFix.cpp @@ -22,6 +22,8 @@ #include "PreCompiled.h" #include "ViewProviderConstraintFix.h" +#include "Mod/Assembly/App/ConstraintFix.h" +#include using namespace AssemblyGui; @@ -32,3 +34,22 @@ ViewProviderConstraintFix::ViewProviderConstraintFix() { sPixmap = "Assembly_ConstraintLock"; } +TopoDS_Shape ViewProviderConstraintFix::getConstraintShape(int link) +{ + if(link == 1) { + + App::DocumentObject* obj = dynamic_cast(pcObject)->First.getValue(); + if(!obj) + return TopoDS_Shape(); + + Assembly::ItemPart* part = static_cast(obj); + if(!part) + return TopoDS_Shape(); + + //return the whole shape + return part->getShape(); + } + + //there is no second link, only one part is fixed per constraint + return TopoDS_Shape(); +} diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraintFix.h b/src/Mod/Assembly/Gui/ViewProviderConstraintFix.h index 66a1e158e..7e0658880 100644 --- a/src/Mod/Assembly/Gui/ViewProviderConstraintFix.h +++ b/src/Mod/Assembly/Gui/ViewProviderConstraintFix.h @@ -24,19 +24,19 @@ #ifndef ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTFIX_H #define ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTFIX_H -#include +#include "ViewProviderConstraint.h" namespace AssemblyGui { -class AssemblyGuiExport ViewProviderConstraintFix : public Gui::ViewProviderDocumentObject { +class AssemblyGuiExport ViewProviderConstraintFix : public ViewProviderConstraint { PROPERTY_HEADER(AssemblyGui::ViewProviderConstraintFix); public: ViewProviderConstraintFix(); - /// checks whether the view provider is visible or not in tree - virtual bool isShow(void) const {return true;}; + // override linked shape as we want to highlight the whole part + TopoDS_Shape getConstraintShape(int link); }; }; diff --git a/src/Mod/Assembly/Gui/ViewProviderConstraintOrientation.h b/src/Mod/Assembly/Gui/ViewProviderConstraintOrientation.h index 4276a46df..3f4bebfc0 100644 --- a/src/Mod/Assembly/Gui/ViewProviderConstraintOrientation.h +++ b/src/Mod/Assembly/Gui/ViewProviderConstraintOrientation.h @@ -24,19 +24,17 @@ #ifndef ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTORIENTATION_H #define ASSEMBLYGUI_VIEWPROVIDERCONSTRAINTORIENTATION_H -#include +#include "ViewProviderConstraint.h" namespace AssemblyGui { -class AssemblyGuiExport ViewProviderConstraintOrientation : public Gui::ViewProviderDocumentObject { +class AssemblyGuiExport ViewProviderConstraintOrientation : public ViewProviderConstraint { PROPERTY_HEADER(AssemblyGui::ViewProviderConstraintOrientation); public: ViewProviderConstraintOrientation(); - /// checks whether the view provider is visible or not in tree - virtual bool isShow(void) const {return true;}; }; };