From 26fb01b4298538f26211c77a16f0fcfe79146f12 Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Tue, 8 Sep 2015 10:45:22 +0300 Subject: [PATCH] PartDesign/Gui: add origin sizing and rework datums sizing --- src/Mod/Part/App/BodyBase.h | 10 ++ src/Mod/Part/App/DatumFeature.cpp | 4 + src/Mod/Part/App/DatumFeature.h | 2 + src/Mod/PartDesign/App/Body.cpp | 36 ------ src/Mod/PartDesign/App/Body.h | 3 - src/Mod/PartDesign/App/DatumLine.cpp | 5 - src/Mod/PartDesign/App/DatumLine.h | 1 - src/Mod/PartDesign/App/DatumPlane.cpp | 5 - src/Mod/PartDesign/App/DatumPlane.h | 1 - src/Mod/PartDesign/Gui/ViewProviderBody.cpp | 113 +++++++++++++----- src/Mod/PartDesign/Gui/ViewProviderBody.h | 15 ++- src/Mod/PartDesign/Gui/ViewProviderDatum.cpp | 109 +++++++++++------ src/Mod/PartDesign/Gui/ViewProviderDatum.h | 48 ++++++-- .../PartDesign/Gui/ViewProviderDatumCS.cpp | 37 +++--- src/Mod/PartDesign/Gui/ViewProviderDatumCS.h | 7 +- .../PartDesign/Gui/ViewProviderDatumLine.cpp | 85 ++++++------- .../PartDesign/Gui/ViewProviderDatumLine.h | 1 + .../PartDesign/Gui/ViewProviderDatumPlane.cpp | 18 ++- .../PartDesign/Gui/ViewProviderDatumPlane.h | 1 + .../PartDesign/Gui/ViewProviderDatumPoint.cpp | 1 + .../PartDesign/Gui/ViewProviderDatumPoint.h | 1 + 21 files changed, 308 insertions(+), 195 deletions(-) diff --git a/src/Mod/Part/App/BodyBase.h b/src/Mod/Part/App/BodyBase.h index 139fb5e49..06482a769 100644 --- a/src/Mod/Part/App/BodyBase.h +++ b/src/Mod/Part/App/BodyBase.h @@ -59,6 +59,16 @@ public: */ App::PropertyLink BaseFeature; + /// Returns all Model objects prepanded by BaseFeature (if any) + std::vector getFullModel () { + std::vector rv; + if ( BaseFeature.getValue () ) { + rv.push_back ( BaseFeature.getValue () ); + } + std::copy ( Model.getValues ().begin (), Model.getValues ().end (), std::back_inserter (rv) ); + return rv; + } + // These methods are located here to avoid a dependency of ViewProviderSketchObject on PartDesign /// Remove the feature from the body virtual void removeFeature(App::DocumentObject* feature){} diff --git a/src/Mod/Part/App/DatumFeature.cpp b/src/Mod/Part/App/DatumFeature.cpp index 750023779..b543588d1 100644 --- a/src/Mod/Part/App/DatumFeature.cpp +++ b/src/Mod/Part/App/DatumFeature.cpp @@ -102,3 +102,7 @@ TopoDS_Shape Datum::getShape() const sh.setPlacement(Placement.getValue()); return sh._Shape; } + +Base::Vector3d Datum::getBasePoint () const { + return Placement.getValue().getPosition(); +} diff --git a/src/Mod/Part/App/DatumFeature.h b/src/Mod/Part/App/DatumFeature.h index 0e744d58d..8aab02e93 100644 --- a/src/Mod/Part/App/DatumFeature.h +++ b/src/Mod/Part/App/DatumFeature.h @@ -54,6 +54,8 @@ public: /// Return a shape including Placement representing the datum feature TopoDS_Shape getShape() const; + /// Returns a point of the feature it counts as it's base + virtual Base::Vector3d getBasePoint () const; protected: void onChanged (const App::Property* prop); void onDocumentRestored(); diff --git a/src/Mod/PartDesign/App/Body.cpp b/src/Mod/PartDesign/App/Body.cpp index 1b879f7cf..fdd25f48a 100644 --- a/src/Mod/PartDesign/App/Body.cpp +++ b/src/Mod/PartDesign/App/Body.cpp @@ -410,42 +410,6 @@ App::DocumentObjectExecReturn *Body::execute(void) } -Base::BoundBox3d Body::getBoundBox() -{ - // TODO review the function (2015-08-31, Fat-Zer) - Base::BoundBox3d result; - - Part::Feature* tipSolid = static_cast(Tip.getValue()); - if (tipSolid && tipSolid->Shape.getValue().IsNull()) { - // This can happen when a new feature is added without having its Shape property set yet - tipSolid = static_cast(getPrevSolidFeature()); - } - - if (!tipSolid || tipSolid->Shape.getValue().IsNull()) { - // TODO check that all callers are correctly handle if bounding box is null (2015-08-31, Fat-Zer) - result = Base::BoundBox3d (); - } else { - result = tipSolid->Shape.getShape().getBoundBox(); - } - - std::vector model = Model.getValues(); - // TODO: In DatumLine and DatumPlane, recalculate the Base point to be as near as possible to the origin (0,0,0) - for (std::vector::const_iterator m = model.begin(); m != model.end(); m++) { - if ((*m)->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())) { - PartDesign::Point* point = static_cast(*m); - result.Add(point->getPoint()); - } else if ((*m)->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) { - PartDesign::Line* line = static_cast(*m); - result.Add(line->getBasePoint()); - } else if ((*m)->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) { - PartDesign::Plane* plane = static_cast(*m); - result.Add(plane->getBasePoint()); - } - } - - return result; -} - void Body::onSettingDocument() { if(connection.connected()) diff --git a/src/Mod/PartDesign/App/Body.h b/src/Mod/PartDesign/App/Body.h index 910e1df56..31c519484 100644 --- a/src/Mod/PartDesign/App/Body.h +++ b/src/Mod/PartDesign/App/Body.h @@ -117,9 +117,6 @@ public: */ static Body *findBodyOf(const App::DocumentObject* feature); - /// Return the bounding box of the Tip Shape, taking into account datum features - Base::BoundBox3d getBoundBox(); - /// Returns the origin link or throws an exception App::Origin *getOrigin () const; diff --git a/src/Mod/PartDesign/App/DatumLine.cpp b/src/Mod/PartDesign/App/DatumLine.cpp index 6ba74a0ef..b3b15ada6 100644 --- a/src/Mod/PartDesign/App/DatumLine.cpp +++ b/src/Mod/PartDesign/App/DatumLine.cpp @@ -100,11 +100,6 @@ void Line::onChanged(const App::Property *prop) Part::Datum::onChanged(prop); } -Base::Vector3d Line::getBasePoint() const -{ - return Placement.getValue().getPosition(); -} - Base::Vector3d Line::getDirection() const { Base::Rotation rot = Placement.getValue().getRotation(); diff --git a/src/Mod/PartDesign/App/DatumLine.h b/src/Mod/PartDesign/App/DatumLine.h index fec043fa7..0d82cd768 100644 --- a/src/Mod/PartDesign/App/DatumLine.h +++ b/src/Mod/PartDesign/App/DatumLine.h @@ -45,7 +45,6 @@ public: return "PartDesignGui::ViewProviderDatumLine"; } - Base::Vector3d getBasePoint() const; Base::Vector3d getDirection() const; protected: diff --git a/src/Mod/PartDesign/App/DatumPlane.cpp b/src/Mod/PartDesign/App/DatumPlane.cpp index aa299ef94..9fa6a811d 100644 --- a/src/Mod/PartDesign/App/DatumPlane.cpp +++ b/src/Mod/PartDesign/App/DatumPlane.cpp @@ -98,11 +98,6 @@ void Plane::onChanged(const App::Property *prop) Part::Datum::onChanged(prop); } -Base::Vector3d Plane::getBasePoint() -{ - return Placement.getValue().getPosition(); -} - Base::Vector3d Plane::getNormal() { Base::Rotation rot = Placement.getValue().getRotation(); diff --git a/src/Mod/PartDesign/App/DatumPlane.h b/src/Mod/PartDesign/App/DatumPlane.h index 545e30fec..92de91d0f 100644 --- a/src/Mod/PartDesign/App/DatumPlane.h +++ b/src/Mod/PartDesign/App/DatumPlane.h @@ -43,7 +43,6 @@ public: return "PartDesignGui::ViewProviderDatumPlane"; } - Base::Vector3d getBasePoint(); Base::Vector3d getNormal(); protected: diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp index 1d5a7fd40..06a590f57 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp @@ -24,16 +24,21 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include # include +# include +# include +# include #endif #include #include +#include #include #include #include +#include +#include +#include #include #include @@ -42,6 +47,7 @@ #include #include +#include "ViewProviderDatum.h" #include "Utils.h" #include "ViewProviderBody.h" @@ -66,7 +72,6 @@ ViewProviderBody::~ViewProviderBody() pcBodyTip->unref (); } - void ViewProviderBody::attach(App::DocumentObject *pcFeat) { // call parent attach method @@ -89,11 +94,13 @@ void ViewProviderBody::attach(App::DocumentObject *pcFeat) // TODO on activating the body switch to the "Through" mode (2015-09-05, Fat-Zer) // TODO differnt icon in tree if mode is Through (2015-09-05, Fat-Zer) // TODO drag&drop (2015-09-05, Fat-Zer) +// TODO Add activate () call (2015-09-08, Fat-Zer) void ViewProviderBody::setDisplayMode(const char* ModeName) { if ( strcmp("Through",ModeName)==0 ) setDisplayMaskMode("Through"); + // TODO Use other Part::features display modes instead of the "Tip" (2015-09-08, Fat-Zer) if ( strcmp("Tip",ModeName)==0 ) setDisplayMaskMode("Tip"); // TODO When switching into Tip mode switch it's visability to true (2015-09-05, Fat-Zer) @@ -110,12 +117,17 @@ bool ViewProviderBody::doubleClicked(void) // assure the PartDesign workbench Gui::Command::assureWorkbench("PartDesignWorkbench"); - //and set correct active objects - auto* part = PartDesignGui::getPartFor(getObject(), false); - if(part!=Gui::Application::Instance->activeView()->getActiveObject(PARTKEY)) - Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PARTKEY, part->getNameInDocument()); + // and set correct active objects + auto* part = App::Part::getPartOfObject ( getObject() ); + if ( part && part != getActiveView()->getActiveObject ( PARTKEY ) ) { + Gui::Command::doCommand ( Gui::Command::Gui, + "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", + PARTKEY, part->getNameInDocument() ); + } - Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PDBODYKEY, this->getObject()->getNameInDocument()); + Gui::Command::doCommand ( Gui::Command::Gui, + "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", + PDBODYKEY, this->getObject()->getNameInDocument() ); return true; } @@ -166,18 +178,20 @@ std::vector ViewProviderBody::claimChildren3D(void)const std::vector rv; - if (body->Origin.getValue()) { // Add origin + if ( body->Origin.getValue() ) { // Add origin rv.push_back (body->Origin.getValue()); } if ( body->BaseFeature.getValue() ) { // Add Base Feature rv.push_back (body->BaseFeature.getValue()); } + // Add all other stuff std::copy (features.begin(), features.end(), std::back_inserter (rv) ); - // TODO Check what will happen if BaseFature will be shared by severral bodies (2015-08-04, Fat-Zer) + return rv; } +// TODO To be deleted (2015-09-08, Fat-Zer) //void ViewProviderBody::updateTree() //{ // if (ActiveGuiDoc == NULL) return; @@ -211,12 +225,11 @@ bool ViewProviderBody::onDelete ( const std::vector &) { void ViewProviderBody::updateData(const App::Property* prop) { - PartDesign::Body* body = static_cast(getObject()); if (prop == &body->Model || prop == &body->BaseFeature) { // update sizes of origins and datums - // TODO Write this (2015-09-05, Fat-Zer) + updateOriginDatumSize (); } else if (prop == &body->Tip) { // Adjust the internals to display App::DocumentObject *tip = body->Tip.getValue (); @@ -225,7 +238,7 @@ void ViewProviderBody::updateData(const App::Property* prop) Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider (tip); if (vp) { SoNode *tipRoot = vp->getRoot (); - if ( pcBodyTip->findChild (tipRoot) == -1 ) { + if ( pcBodyTip->findChild ( tipRoot ) == -1 ) { pcBodyTip->removeAllChildren (); pcBodyTip->addChild ( tipRoot ); } @@ -238,23 +251,67 @@ void ViewProviderBody::updateData(const App::Property* prop) } } - // TODO rewrite this, it's quite a hacky way of notifying (2015-09-05, Fat-Zer) - std::vector features = body->Model.getValues(); - for (std::vector::const_iterator f = features.begin(); f != features.end(); f++) { - App::PropertyPlacement* plm = NULL; - if ((*f)->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) - plm = &(static_cast(*f)->Placement); - else if ((*f)->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) - plm = &(static_cast(*f)->Placement); - else if ((*f)->getTypeId().isDerivedFrom(PartDesign::CoordinateSystem::getClassTypeId())) - plm = &(static_cast(*f)->Placement); + PartGui::ViewProviderPart::updateData(prop); +} - if (plm != NULL) { - Gui::ViewProviderDocumentObject* vp = dynamic_cast(Gui::Application::Instance->getViewProvider(*f)); - if (vp != NULL) - vp->updateData(plm); +void ViewProviderBody::updateOriginDatumSize () { + PartDesign::Body *body = static_cast ( getObject() ); + // Use different bounding boxes for datums and for origins: + Gui::View3DInventorViewer* viewer = static_cast(this->getActiveView())->getViewer(); + SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion()); + + const auto & model = body->getFullModel (); + + // BBox for Datums is calculated from all visible objects but treating datums as their basepoints only + SbBox3f bboxDatums = ViewProviderDatum::getRelevantBoundBox ( bboxAction, model ); + // BBox for origin should take into account datums size also + SbBox3f bboxOrigins = bboxDatums; + + for(App::DocumentObject* obj : model) { + if ( obj->isDerivedFrom ( Part::Datum::getClassTypeId () ) ) { + ViewProvider *vp = Gui::Application::Instance->getViewProvider(obj); + if (!vp) { continue; } + + ViewProviderDatum *vpDatum = static_cast (vp) ; + + vpDatum->setExtents ( bboxDatums ); + + bboxAction.apply ( vp->getRoot () ); + bboxOrigins.extendBy ( bboxAction.getBoundingBox () ); } } - PartGui::ViewProviderPart::updateData(prop); + // get the bounding box values + SbVec3f max = bboxOrigins.getMax(); + SbVec3f min = bboxOrigins.getMin(); + + // obtain an Origin and it's ViewProvider + App::Origin* origin = 0; + Gui::ViewProviderOrigin* vpOrigin = 0; + try { + origin = body->getOrigin (); + assert (origin); + + Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider(origin); + if (!vp) { + throw Base::Exception ("No view provider linked to the Origin"); + } + assert ( vp->isDerivedFrom ( Gui::ViewProviderOrigin::getClassTypeId () ) ); + vpOrigin = static_cast ( vp ); + } catch (const Base::Exception &ex) { + Base::Console().Error ("%s\n", ex.what() ); + return; + } + + // calculate the desired origin size + Base::Vector3d size; + + for (uint_fast8_t i=0; i<3; i++) { + size[i] = std::max ( fabs ( max[i] ), fabs ( min[i] ) ); + if (size[i] < Precision::Confusion() ) { + size[i] = Gui::ViewProviderOrigin::defaultSize(); + } + } + + vpOrigin->Size.setValue ( size*1.2 ); } diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.h b/src/Mod/PartDesign/Gui/ViewProviderBody.h index b5050b6b9..ecdcf0f63 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.h +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.h @@ -28,7 +28,8 @@ class SoGroup; class SoSeparator; - +class SbBox3f; +class SoGetBoundingBoxAction; namespace PartDesignGui { /** ViewProvider of the Body feature @@ -62,8 +63,16 @@ public: virtual bool onDelete(const std::vector &); /// Update the children's highlighting when triggered - void updateData(const App::Property* prop); + virtual void updateData(const App::Property* prop); + /// Update the sizes of origin and datums + void updateOriginDatumSize (); + + /** + * Return the bounding box of visible features + * @note datums are counted as their base point only + */ + SbBox3f getBoundBox (); private: /// group used to store children collected by claimChildren3D() in the through (edit) mode. SoGroup *pcBodyChildren; @@ -72,8 +81,6 @@ private: /// Update the children's highlighting //void updateTree(); - - }; diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp index add048f39..39e507079 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp @@ -27,6 +27,7 @@ # include # include # include +# include # include # include # include @@ -52,10 +53,13 @@ #endif #include +#include #include #include #include #include +#include +#include #include #include @@ -64,6 +68,7 @@ #include #include "TaskDatumParameters.h" +#include "ViewProviderBody.h" #include "Utils.h" #include "ViewProviderDatum.h" @@ -73,7 +78,7 @@ using namespace PartDesignGui; PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,Gui::ViewProviderGeometryObject) ViewProviderDatum::ViewProviderDatum() -{ +{ pShapeSep = new SoSeparator(); pShapeSep->ref(); @@ -304,39 +309,73 @@ void ViewProviderDatum::unsetEdit(int ModNum) } } -Base::BoundBox3d ViewProviderDatum::getRelevantExtents() -{ - Base::BoundBox3d bbox; - PartDesign::Body* body = static_cast(Part::BodyBase::findBodyOf(this->getObject())); - if (body != NULL) - bbox = body->getBoundBox(); - else { - App::DocumentObjectGroup* group = App::DocumentObjectGroup::getGroupOfObject(this->getObject()); - std::vector objs; - - if(group) - objs = group->getObjectsOfType(Part::Feature::getClassTypeId()); - else - objs = this->getObject()->getDocument()->getObjectsOfType(Part::Feature::getClassTypeId()); - - for(App::DocumentObject* obj: objs){ - Part::Feature* feat = static_cast(obj); - Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(feat); - if (vp->isVisible()){ - Base::BoundBox3d bbf = feat->Shape.getBoundingBox(); - if (bbf.CalcDiagonalLength() < Precision::Infinite()) - bbox.Add(bbf); - } - - } - if (bbox.CalcDiagonalLength() < Precision::Confusion()){ - bbox.Add(Base::Vector3d(-10.0,-10.0,-10.0)); - bbox.Add(Base::Vector3d(10.0,10.0,10.0)); - } - - } - bbox.Enlarge(0.1 * bbox.CalcDiagonalLength()); - return bbox; - +void ViewProviderDatum::updateExtents () { + setExtents ( getRelevantBoundBox () ); } +void ViewProviderDatum::setExtents (const SbBox3f &bbox) { + const SbVec3f & min = bbox.getMin (); + const SbVec3f & max = bbox.getMax (); + setExtents ( Base::BoundBox3d ( min.getValue()[0], min.getValue()[1], min.getValue()[2], + max.getValue()[0], max.getValue()[1], max.getValue()[2] ) ); +} + +SbBox3f ViewProviderDatum::getRelevantBoundBox () const { + std::vector objs; + + // Probe body first + PartDesign::Body* body = PartDesign::Body::findBodyOf ( this->getObject() ); + if (body) { + objs = body->getFullModel (); + } else { + // Probe if we belongs to some group + App::DocumentObjectGroup* group = App::DocumentObjectGroup::getGroupOfObject ( this->getObject () ); + + if(group) { + objs = group->getObjects (); + } else { + // Fallback to whole document + objs = this->getObject ()->getDocument ()->getObjects (); + } + } + + Gui::View3DInventorViewer* viewer = static_cast(this->getActiveView())->getViewer(); + SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion()); + SbBox3f bbox = getRelevantBoundBox (bboxAction, objs); + + if ( bbox.getVolume () < Precision::Confusion() ) { + bbox.extendBy ( SbVec3f (-10.0,-10.0,-10.0) ); + bbox.extendBy ( SbVec3f ( 10.0, 10.0, 10.0) ); + } + + return bbox; +} + +SbBox3f ViewProviderDatum::getRelevantBoundBox ( + SoGetBoundingBoxAction &bboxAction, const std::vector &objs ) +{ + SbBox3f bbox(0,0,0, 0,0,0); + + // Adds the bbox of given feature to the output + for (auto obj :objs) { + ViewProvider *vp = Gui::Application::Instance->getViewProvider(obj); + if (!vp) { continue; } + if (!vp->isVisible ()) { continue; } + + if (obj->isDerivedFrom (Part::Datum::getClassTypeId() ) ) { + // Treat datums only as their basepoint + // I hope it's ok to take FreeCAD's point here + Base::Vector3d basePoint = static_cast ( obj )->getBasePoint (); + bbox.extendBy (SbVec3f(basePoint.x, basePoint.y, basePoint.z )); + } else { + bboxAction.apply ( vp->getRoot () ); + SbBox3f obj_bbox = bboxAction.getBoundingBox (); + + if ( obj_bbox.getVolume () < Precision::Infinite () ) { + bbox.extendBy ( obj_bbox ); + } + } + } + + return bbox; +} diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.h b/src/Mod/PartDesign/Gui/ViewProviderDatum.h index 10fdcfad2..92322459a 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatum.h +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.h @@ -27,6 +27,9 @@ #include "Gui/ViewProviderGeometryObject.h" #include +class SbBox3f; +class SoGetBoundingBoxAction; + namespace PartDesignGui { class PartDesignGuiExport ViewProviderDatum : public Gui::ViewProviderGeometryObject @@ -39,7 +42,7 @@ public: /// destructor virtual ~ViewProviderDatum(); - /// grouping handling + /// grouping handling void setupContextMenu(QMenu*, QObject*, const char*); virtual void attach(App::DocumentObject *); @@ -57,26 +60,49 @@ public: virtual std::string getElement(const SoDetail *) const; virtual SoDetail* getDetail(const char*) const; + /** + * Update the visual size to match the given extents + * @note should be reimplemented in the offspings + * @note use FreeCAD-specific bbox here to simplify the math in derived classes + */ + virtual void setExtents (Base::BoundBox3d bbox) + { } + + /// Update the visual sizes. This overloaded version of the previous function to allow pass coin type + void setExtents (const SbBox3f &bbox); + + /// update size to match the guessed bounding box + void updateExtents (); + /// The datum type (Plane, Line or Point) + // TODO remove this atribute (2015-09-08, Fat-Zer) QString datumType; + /** + * Computes apropriate bounding box for the given list of objects to be passed to setExtents () + * @param bboxAction a coin action for traverse the given objects views. + * @param objs the list of objects to traverse, due to we traverse the scene graph, the geo children + * will likely be traveresed too. + */ + static SbBox3f getRelevantBoundBox ( + SoGetBoundingBoxAction &bboxAction, + const std::vector &objs); + protected: void onChanged(const App::Property* prop); virtual bool setEdit(int ModNum); virtual void unsetEdit(int ModNum); - - // /** - * @brief getRelevantExtents computes the bounding box of the objects - * relevant to the datum feature, which is intended to be used for - * determinimg the size of the rendered piece of the datum. - * @return Bounding box of body, if the datum is in a body. Bounding box of - * all visible shapes of a part, if in a part but not in a body. Bounding - * box of all visible Part::Feature-derived objects if just in a document. - * This behavior is subject to change. + * Gueses the context this datum belongs to and returns apropriate bounding box of all + * visiable content of the feature + * + * Currently known contexts are: + * - PartDesign::Body + * - App::DocumentObjectGroup (App::Part as well as subclass) + * - Whole document */ - virtual Base::BoundBox3d getRelevantExtents(); + SbBox3f getRelevantBoundBox() const; protected: SoSeparator* pShapeSep; diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatumCS.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatumCS.cpp index 1bb053339..8adcbee1d 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatumCS.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatumCS.cpp @@ -62,7 +62,7 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumCoordinateSystem,PartDesignGui:: ViewProviderDatumCoordinateSystem::ViewProviderDatumCoordinateSystem() { sPixmap = "PartDesign_CoordinateSystem.svg"; - + SoMaterial* material = new SoMaterial(); material->diffuseColor.setNum(4); material->diffuseColor.set1Value(0, SbColor(0.f, 0.f, 0.f)); @@ -73,7 +73,7 @@ ViewProviderDatumCoordinateSystem::ViewProviderDatumCoordinateSystem() binding->value = SoMaterialBinding::PER_FACE_INDEXED; pShapeSep->addChild(binding); pShapeSep->addChild(material); - + font = new SoFont(); font->ref(); transX = new SoTranslation(); @@ -95,15 +95,21 @@ ViewProviderDatumCoordinateSystem::~ViewProviderDatumCoordinateSystem() void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop) { if (strcmp(prop->getName(),"Placement") == 0) { - - + updateExtents (); + } + + ViewProviderDatum::updateData(prop); +} + +void ViewProviderDatumCoordinateSystem::setExtents (Base::BoundBox3d bbox) { + // TODO Review the function (2015-09-08, Fat-Zer) Base::Vector3d base(0,0,0); Base::Vector3d dir(0,0,1); Base::Vector3d x, y, z; - getPointForDirection(Base::Vector3d(1,0,0), x); - getPointForDirection(Base::Vector3d(0,1,0), y); - getPointForDirection(Base::Vector3d(0,0,1), z); - + getPointForDirection(Base::Vector3d(1,0,0), bbox, x); + getPointForDirection(Base::Vector3d(0,1,0), bbox, y); + getPointForDirection(Base::Vector3d(0,0,1), bbox, z); + //normalize all to equal lengths Base::Vector3d axis = (x.Sqr() > y.Sqr()) ? x : y; axis = (axis.Sqr() > z.Sqr()) ? axis : z; @@ -141,7 +147,7 @@ void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop) lineSet->materialIndex.set1Value(1,2); lineSet->materialIndex.set1Value(2,3); pShapeSep->addChild(lineSet); - + pShapeSep->addChild(font); font->size = axis.Length()/10.; pShapeSep->addChild(transX); @@ -162,14 +168,14 @@ void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop) t = new SoAsciiText(); t->string = "Z"; pShapeSep->addChild(t); - + } else { coord = static_cast(pShapeSep->getChild(2)); coord->point.set1Value(0, base.x, base.y, base.z); coord->point.set1Value(1, x.x, x.y, x.z); coord->point.set1Value(2, y.x, y.y, y.z); coord->point.set1Value(3, z.x, z.y, z.z); - + x = 9./10.*x; y = 9./10.*y; font->size = axis.Length()/10.; @@ -177,24 +183,21 @@ void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop) transY->translation.setValue(SbVec3f(-x.x + y.x, x.y + y.y, -x.z + y.z)); transZ->translation.setValue(SbVec3f(-y.x + z.x, -y.y + z.y, -y.z + z.z)); } - } - - ViewProviderDatum::updateData(prop); } -void ViewProviderDatumCoordinateSystem::getPointForDirection(Base::Vector3d dir, Base::Vector3d& p) { +void ViewProviderDatumCoordinateSystem::getPointForDirection(Base::Vector3d dir, const Base::BoundBox3d& in_bbox, Base::Vector3d& p) { // Gets called whenever a property of the attached object changes PartDesign::CoordinateSystem* pcDatum = static_cast(this->getObject()); Base::Placement plm = pcDatum->Placement.getValue(); plm.invert(); - + Base::Vector3d base(0,0,0); // Get limits of the line from bounding box of the body PartDesign::Body* body = static_cast(Part::BodyBase::findBodyOf(this->getObject())); if (body == NULL) return; - Base::BoundBox3d bbox = body->getBoundBox(); + Base::BoundBox3d bbox = in_bbox; bbox = bbox.Transformed(plm.toMatrix()); bbox.Enlarge(0.1 * bbox.CalcDiagonalLength()); if (bbox.IsInBox(base)) { diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatumCS.h b/src/Mod/PartDesign/Gui/ViewProviderDatumCS.h index 487386fb5..b10f5b9e8 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatumCS.h +++ b/src/Mod/PartDesign/Gui/ViewProviderDatumCS.h @@ -42,10 +42,11 @@ public: virtual ~ViewProviderDatumCoordinateSystem(); virtual void updateData(const App::Property*); - + + virtual void setExtents (Base::BoundBox3d bbox); private: - void getPointForDirection(Base::Vector3d Dir, Base::Vector3d& p); - + void getPointForDirection(Base::Vector3d Dir, const Base::BoundBox3d& bbox, Base::Vector3d& p); + SoTranslation *transX, *transY, *transZ; SoFont* font; }; diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatumLine.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatumLine.cpp index 74cf6b97e..bb60d58a1 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatumLine.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatumLine.cpp @@ -54,7 +54,7 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumLine,PartDesignGui::ViewProvider ViewProviderDatumLine::ViewProviderDatumLine() { sPixmap = "PartDesign_Line.svg"; - + // TODO Let the base class handle material (2015-09-07, Fat-Zer) SoMaterial* material = new SoMaterial(); material->diffuseColor.setValue(0.9f, 0.9f, 0.13f); material->transparency.setValue(0.2f); @@ -72,47 +72,52 @@ void ViewProviderDatumLine::updateData(const App::Property* prop) PartDesign::Line* pcDatum = static_cast(this->getObject()); if (strcmp(prop->getName(),"Placement") == 0) { - Base::Placement plm = pcDatum->Placement.getValue(); - plm.invert(); - Base::Vector3d base(0,0,0); - Base::Vector3d dir(0,0,1); - - // Get limits of the line from bounding box of the body - Base::BoundBox3d bbox = this->getRelevantExtents(); - - bbox = bbox.Transformed(plm.toMatrix()); - Base::Vector3d p1, p2; - if (bbox.IsInBox(base)) { - bbox.IntersectionPoint(base, dir, p1, Precision::Confusion()); - bbox.IntersectionPoint(base, -dir, p2, Precision::Confusion()); - } else { - bbox.IntersectWithLine(base, dir, p1, p2); - if ((p1 == Base::Vector3d(0,0,0)) && (p2 == Base::Vector3d(0,0,0))) - bbox.IntersectWithLine(base, -dir, p1, p2); - } - - // Display the line - PartGui::SoBrepEdgeSet* lineSet; - SoCoordinate3* coord; - - if (pShapeSep->getNumChildren() == 1) { - coord = new SoCoordinate3(); - coord->point.setNum(2); - coord->point.set1Value(0, p1.x, p1.y, p1.z); - coord->point.set1Value(1, p2.x, p2.y, p2.z); - pShapeSep->addChild(coord); - lineSet = new PartGui::SoBrepEdgeSet(); - lineSet->coordIndex.setNum(2); - lineSet->coordIndex.set1Value(0, 0); - lineSet->coordIndex.set1Value(1, 1); - pShapeSep->addChild(lineSet); - } else { - coord = static_cast(pShapeSep->getChild(1)); - coord->point.set1Value(0, p1.x, p1.y, p1.z); - coord->point.set1Value(1, p2.x, p2.y, p2.z); - } + updateExtents (); } ViewProviderDatum::updateData(prop); } + +void ViewProviderDatumLine::setExtents (Base::BoundBox3d bbox) { + PartDesign::Line* pcDatum = static_cast(this->getObject()); + + Base::Placement plm = pcDatum->Placement.getValue(); + plm.invert(); + Base::Vector3d base(0,0,0); + Base::Vector3d dir(0,0,1); + + // TODO transform point rather the bbox (2015-09-07, Fat-Zer) + Base::BoundBox3d my_bbox = bbox.Transformed(plm.toMatrix()); + Base::Vector3d p1, p2; + if (my_bbox.IsInBox(base)) { + my_bbox.IntersectionPoint(base, dir, p1, Precision::Confusion()); + my_bbox.IntersectionPoint(base, -dir, p2, Precision::Confusion()); + } else { + my_bbox.IntersectWithLine(base, dir, p1, p2); + if ((p1 == Base::Vector3d(0,0,0)) && (p2 == Base::Vector3d(0,0,0))) + my_bbox.IntersectWithLine(base, -dir, p1, p2); + } + + // Display the line + PartGui::SoBrepEdgeSet* lineSet; + SoCoordinate3* coord; + + // TODO Move initialization to the attach() (2015-09-07, Fat-Zer) + if (pShapeSep->getNumChildren() == 1) { + coord = new SoCoordinate3(); + coord->point.setNum(2); + coord->point.set1Value(0, p1.x, p1.y, p1.z); + coord->point.set1Value(1, p2.x, p2.y, p2.z); + pShapeSep->addChild(coord); + lineSet = new PartGui::SoBrepEdgeSet(); + lineSet->coordIndex.setNum(2); + lineSet->coordIndex.set1Value(0, 0); + lineSet->coordIndex.set1Value(1, 1); + pShapeSep->addChild(lineSet); + } else { + coord = static_cast(pShapeSep->getChild(1)); + coord->point.set1Value(0, p1.x, p1.y, p1.z); + coord->point.set1Value(1, p2.x, p2.y, p2.z); + } +} diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatumLine.h b/src/Mod/PartDesign/Gui/ViewProviderDatumLine.h index 60e7fb2fe..a0a62438d 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatumLine.h +++ b/src/Mod/PartDesign/Gui/ViewProviderDatumLine.h @@ -40,6 +40,7 @@ public: virtual void updateData(const App::Property*); + virtual void setExtents (Base::BoundBox3d bbox); }; } // namespace PartDesignGui diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatumPlane.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatumPlane.cpp index 40a075685..56070ccd9 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatumPlane.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatumPlane.cpp @@ -55,7 +55,7 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumPlane,PartDesignGui::ViewProvide ViewProviderDatumPlane::ViewProviderDatumPlane() { sPixmap = "PartDesign_Plane.svg"; - + // TODO Use general material object (2015-09-07, Fat-Zer) SoMaterial* material = new SoMaterial(); material->diffuseColor.setValue(0.9f, 0.9f, 0.13f); material->transparency.setValue(0.5f); @@ -73,13 +73,23 @@ void ViewProviderDatumPlane::updateData(const App::Property* prop) PartDesign::Plane* pcDatum = static_cast(this->getObject()); if (strcmp(prop->getName(),"Placement") == 0) { + updateExtents (); + } + + ViewProviderDatum::updateData(prop); +} + + +void ViewProviderDatumPlane::setExtents (Base::BoundBox3d bbox) { + PartDesign::Plane* pcDatum = static_cast(this->getObject()); + Base::Placement plm = pcDatum->Placement.getValue(); + plm.invert(); Base::Vector3d base(0,0,0); Base::Vector3d normal(0,0,1); // Get limits of the plane from bounding box of the body - Base::BoundBox3d bbox = this->getRelevantExtents(); bbox = bbox.Transformed(plm.toMatrix()); double dlength = bbox.CalcDiagonalLength(); if (dlength < Precision::Confusion()) @@ -246,9 +256,5 @@ void ViewProviderDatumPlane::updateData(const App::Property* prop) lineSet->coordIndex.set1Value(points.size(), 0); lineSet->coordIndex.set1Value(points.size()+1, SO_END_LINE_INDEX); } - } - - ViewProviderDatum::updateData(prop); } - diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatumPlane.h b/src/Mod/PartDesign/Gui/ViewProviderDatumPlane.h index 53c23ecb5..97705d6cf 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatumPlane.h +++ b/src/Mod/PartDesign/Gui/ViewProviderDatumPlane.h @@ -40,6 +40,7 @@ public: virtual void updateData(const App::Property*); + void setExtents (Base::BoundBox3d bbox); }; } // namespace PartDesignGui diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatumPoint.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatumPoint.cpp index 9aa9ac094..929a08ede 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatumPoint.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatumPoint.cpp @@ -66,6 +66,7 @@ ViewProviderDatumPoint::~ViewProviderDatumPoint() void ViewProviderDatumPoint::updateData(const App::Property* prop) { + // TODO Review this (2015-09-07, Fat-Zer) if (strcmp(prop->getName(),"Placement") == 0) { // The only reason to do this is to display the point in the correct position after loading the document SoMarkerSet* marker = static_cast(pShapeSep->getChild(1)); diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatumPoint.h b/src/Mod/PartDesign/Gui/ViewProviderDatumPoint.h index 68edadeca..91e8ba196 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatumPoint.h +++ b/src/Mod/PartDesign/Gui/ViewProviderDatumPoint.h @@ -40,6 +40,7 @@ public: virtual void updateData(const App::Property*); + // Note: don't overload setExtents () here because point doesn't really depends on it }; } // namespace PartDesignGui