PartDesign/Gui: add origin sizing and rework datums sizing

This commit is contained in:
Alexander Golubev 2015-09-08 10:45:22 +03:00 committed by Stefan Tröger
parent 56823eeb9d
commit 26fb01b429
21 changed files with 308 additions and 195 deletions

View File

@ -59,6 +59,16 @@ public:
*/ */
App::PropertyLink BaseFeature; App::PropertyLink BaseFeature;
/// Returns all Model objects prepanded by BaseFeature (if any)
std::vector<App::DocumentObject *> getFullModel () {
std::vector<App::DocumentObject *> 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 // These methods are located here to avoid a dependency of ViewProviderSketchObject on PartDesign
/// Remove the feature from the body /// Remove the feature from the body
virtual void removeFeature(App::DocumentObject* feature){} virtual void removeFeature(App::DocumentObject* feature){}

View File

@ -102,3 +102,7 @@ TopoDS_Shape Datum::getShape() const
sh.setPlacement(Placement.getValue()); sh.setPlacement(Placement.getValue());
return sh._Shape; return sh._Shape;
} }
Base::Vector3d Datum::getBasePoint () const {
return Placement.getValue().getPosition();
}

View File

@ -54,6 +54,8 @@ public:
/// Return a shape including Placement representing the datum feature /// Return a shape including Placement representing the datum feature
TopoDS_Shape getShape() const; TopoDS_Shape getShape() const;
/// Returns a point of the feature it counts as it's base
virtual Base::Vector3d getBasePoint () const;
protected: protected:
void onChanged (const App::Property* prop); void onChanged (const App::Property* prop);
void onDocumentRestored(); void onDocumentRestored();

View File

@ -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<Part::Feature*>(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<Part::Feature*>(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<App::DocumentObject*> 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<App::DocumentObject*>::const_iterator m = model.begin(); m != model.end(); m++) {
if ((*m)->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())) {
PartDesign::Point* point = static_cast<PartDesign::Point*>(*m);
result.Add(point->getPoint());
} else if ((*m)->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) {
PartDesign::Line* line = static_cast<PartDesign::Line*>(*m);
result.Add(line->getBasePoint());
} else if ((*m)->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) {
PartDesign::Plane* plane = static_cast<PartDesign::Plane*>(*m);
result.Add(plane->getBasePoint());
}
}
return result;
}
void Body::onSettingDocument() { void Body::onSettingDocument() {
if(connection.connected()) if(connection.connected())

View File

@ -117,9 +117,6 @@ public:
*/ */
static Body *findBodyOf(const App::DocumentObject* feature); 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 /// Returns the origin link or throws an exception
App::Origin *getOrigin () const; App::Origin *getOrigin () const;

View File

@ -100,11 +100,6 @@ void Line::onChanged(const App::Property *prop)
Part::Datum::onChanged(prop); Part::Datum::onChanged(prop);
} }
Base::Vector3d Line::getBasePoint() const
{
return Placement.getValue().getPosition();
}
Base::Vector3d Line::getDirection() const Base::Vector3d Line::getDirection() const
{ {
Base::Rotation rot = Placement.getValue().getRotation(); Base::Rotation rot = Placement.getValue().getRotation();

View File

@ -45,7 +45,6 @@ public:
return "PartDesignGui::ViewProviderDatumLine"; return "PartDesignGui::ViewProviderDatumLine";
} }
Base::Vector3d getBasePoint() const;
Base::Vector3d getDirection() const; Base::Vector3d getDirection() const;
protected: protected:

View File

@ -98,11 +98,6 @@ void Plane::onChanged(const App::Property *prop)
Part::Datum::onChanged(prop); Part::Datum::onChanged(prop);
} }
Base::Vector3d Plane::getBasePoint()
{
return Placement.getValue().getPosition();
}
Base::Vector3d Plane::getNormal() Base::Vector3d Plane::getNormal()
{ {
Base::Rotation rot = Placement.getValue().getRotation(); Base::Rotation rot = Placement.getValue().getRotation();

View File

@ -43,7 +43,6 @@ public:
return "PartDesignGui::ViewProviderDatumPlane"; return "PartDesignGui::ViewProviderDatumPlane";
} }
Base::Vector3d getBasePoint();
Base::Vector3d getNormal(); Base::Vector3d getNormal();
protected: protected:

View File

@ -24,16 +24,21 @@
#include "PreCompiled.h" #include "PreCompiled.h"
#ifndef _PreComp_ #ifndef _PreComp_
# include <algorithm>
# include <Inventor/nodes/SoGroup.h>
# include <Inventor/nodes/SoSeparator.h> # include <Inventor/nodes/SoSeparator.h>
# include <Inventor/actions/SoGetBoundingBoxAction.h>
# include <Inventor/SbBox3d.h>
# include <Precision.hxx>
#endif #endif
#include <Base/Console.h> #include <Base/Console.h>
#include <App/Part.h> #include <App/Part.h>
#include <App/Origin.h>
#include <Gui/Command.h> #include <Gui/Command.h>
#include <Gui/Document.h> #include <Gui/Document.h>
#include <Gui/Application.h> #include <Gui/Application.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/ViewProviderOrigin.h>
#include <Mod/PartDesign/App/Body.h> #include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeatureSketchBased.h> #include <Mod/PartDesign/App/FeatureSketchBased.h>
@ -42,6 +47,7 @@
#include <Mod/PartDesign/App/DatumPlane.h> #include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/PartDesign/App/DatumCS.h> #include <Mod/PartDesign/App/DatumCS.h>
#include "ViewProviderDatum.h"
#include "Utils.h" #include "Utils.h"
#include "ViewProviderBody.h" #include "ViewProviderBody.h"
@ -66,7 +72,6 @@ ViewProviderBody::~ViewProviderBody()
pcBodyTip->unref (); pcBodyTip->unref ();
} }
void ViewProviderBody::attach(App::DocumentObject *pcFeat) void ViewProviderBody::attach(App::DocumentObject *pcFeat)
{ {
// call parent attach method // 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 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 differnt icon in tree if mode is Through (2015-09-05, Fat-Zer)
// TODO drag&drop (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) void ViewProviderBody::setDisplayMode(const char* ModeName)
{ {
if ( strcmp("Through",ModeName)==0 ) if ( strcmp("Through",ModeName)==0 )
setDisplayMaskMode("Through"); setDisplayMaskMode("Through");
// TODO Use other Part::features display modes instead of the "Tip" (2015-09-08, Fat-Zer)
if ( strcmp("Tip",ModeName)==0 ) if ( strcmp("Tip",ModeName)==0 )
setDisplayMaskMode("Tip"); setDisplayMaskMode("Tip");
// TODO When switching into Tip mode switch it's visability to true (2015-09-05, Fat-Zer) // TODO When switching into Tip mode switch it's visability to true (2015-09-05, Fat-Zer)
@ -111,11 +118,16 @@ bool ViewProviderBody::doubleClicked(void)
Gui::Command::assureWorkbench("PartDesignWorkbench"); Gui::Command::assureWorkbench("PartDesignWorkbench");
// and set correct active objects // and set correct active objects
auto* part = PartDesignGui::getPartFor(getObject(), false); auto* part = App::Part::getPartOfObject ( getObject() );
if(part!=Gui::Application::Instance->activeView()->getActiveObject<App::Part*>(PARTKEY)) if ( part && part != getActiveView()->getActiveObject<App::Part*> ( 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)",
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; return true;
} }
@ -173,11 +185,13 @@ std::vector<App::DocumentObject*> ViewProviderBody::claimChildren3D(void)const
rv.push_back (body->BaseFeature.getValue()); rv.push_back (body->BaseFeature.getValue());
} }
// Add all other stuff
std::copy (features.begin(), features.end(), std::back_inserter (rv) ); 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; return rv;
} }
// TODO To be deleted (2015-09-08, Fat-Zer)
//void ViewProviderBody::updateTree() //void ViewProviderBody::updateTree()
//{ //{
// if (ActiveGuiDoc == NULL) return; // if (ActiveGuiDoc == NULL) return;
@ -211,12 +225,11 @@ bool ViewProviderBody::onDelete ( const std::vector<std::string> &) {
void ViewProviderBody::updateData(const App::Property* prop) void ViewProviderBody::updateData(const App::Property* prop)
{ {
PartDesign::Body* body = static_cast<PartDesign::Body*>(getObject()); PartDesign::Body* body = static_cast<PartDesign::Body*>(getObject());
if (prop == &body->Model || prop == &body->BaseFeature) { if (prop == &body->Model || prop == &body->BaseFeature) {
// update sizes of origins and datums // update sizes of origins and datums
// TODO Write this (2015-09-05, Fat-Zer) updateOriginDatumSize ();
} else if (prop == &body->Tip) { } else if (prop == &body->Tip) {
// Adjust the internals to display // Adjust the internals to display
App::DocumentObject *tip = body->Tip.getValue (); App::DocumentObject *tip = body->Tip.getValue ();
@ -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<App::DocumentObject*> features = body->Model.getValues();
for (std::vector<App::DocumentObject*>::const_iterator f = features.begin(); f != features.end(); f++) {
App::PropertyPlacement* plm = NULL;
if ((*f)->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId()))
plm = &(static_cast<PartDesign::Line*>(*f)->Placement);
else if ((*f)->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId()))
plm = &(static_cast<PartDesign::Plane*>(*f)->Placement);
else if ((*f)->getTypeId().isDerivedFrom(PartDesign::CoordinateSystem::getClassTypeId()))
plm = &(static_cast<PartDesign::CoordinateSystem*>(*f)->Placement);
if (plm != NULL) {
Gui::ViewProviderDocumentObject* vp = dynamic_cast<Gui::ViewProviderDocumentObject*>(Gui::Application::Instance->getViewProvider(*f));
if (vp != NULL)
vp->updateData(plm);
}
}
PartGui::ViewProviderPart::updateData(prop); PartGui::ViewProviderPart::updateData(prop);
} }
void ViewProviderBody::updateOriginDatumSize () {
PartDesign::Body *body = static_cast<PartDesign::Body *> ( getObject() );
// Use different bounding boxes for datums and for origins:
Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(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 <ViewProviderDatum *> (vp) ;
vpDatum->setExtents ( bboxDatums );
bboxAction.apply ( vp->getRoot () );
bboxOrigins.extendBy ( bboxAction.getBoundingBox () );
}
}
// 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 <Gui::ViewProviderOrigin *> ( 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 );
}

View File

@ -28,7 +28,8 @@
class SoGroup; class SoGroup;
class SoSeparator; class SoSeparator;
class SbBox3f;
class SoGetBoundingBoxAction;
namespace PartDesignGui { namespace PartDesignGui {
/** ViewProvider of the Body feature /** ViewProvider of the Body feature
@ -62,8 +63,16 @@ public:
virtual bool onDelete(const std::vector<std::string> &); virtual bool onDelete(const std::vector<std::string> &);
/// Update the children's highlighting when triggered /// 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: private:
/// group used to store children collected by claimChildren3D() in the through (edit) mode. /// group used to store children collected by claimChildren3D() in the through (edit) mode.
SoGroup *pcBodyChildren; SoGroup *pcBodyChildren;
@ -72,8 +81,6 @@ private:
/// Update the children's highlighting /// Update the children's highlighting
//void updateTree(); //void updateTree();
}; };

View File

@ -27,6 +27,7 @@
# include <QMessageBox> # include <QMessageBox>
# include <QAction> # include <QAction>
# include <QMenu> # include <QMenu>
# include <Inventor/actions/SoGetBoundingBoxAction.h>
# include <Inventor/nodes/SoSeparator.h> # include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoPickStyle.h> # include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoShapeHints.h> # include <Inventor/nodes/SoShapeHints.h>
@ -52,10 +53,13 @@
#endif #endif
#include <App/DocumentObjectGroup.h> #include <App/DocumentObjectGroup.h>
#include <App/GeoFeatureGroup.h>
#include <Gui/Control.h> #include <Gui/Control.h>
#include <Gui/Command.h> #include <Gui/Command.h>
#include <Gui/Application.h> #include <Gui/Application.h>
#include <Gui/MDIView.h> #include <Gui/MDIView.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Mod/PartDesign/App/DatumPoint.h> #include <Mod/PartDesign/App/DatumPoint.h>
#include <Mod/PartDesign/App/DatumLine.h> #include <Mod/PartDesign/App/DatumLine.h>
@ -64,6 +68,7 @@
#include <Mod/PartDesign/App/DatumCS.h> #include <Mod/PartDesign/App/DatumCS.h>
#include "TaskDatumParameters.h" #include "TaskDatumParameters.h"
#include "ViewProviderBody.h"
#include "Utils.h" #include "Utils.h"
#include "ViewProviderDatum.h" #include "ViewProviderDatum.h"
@ -304,39 +309,73 @@ void ViewProviderDatum::unsetEdit(int ModNum)
} }
} }
Base::BoundBox3d ViewProviderDatum::getRelevantExtents() void ViewProviderDatum::updateExtents () {
{ setExtents ( getRelevantBoundBox () );
Base::BoundBox3d bbox; }
PartDesign::Body* body = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(this->getObject()));
if (body != NULL) void ViewProviderDatum::setExtents (const SbBox3f &bbox) {
bbox = body->getBoundBox(); const SbVec3f & min = bbox.getMin ();
else { const SbVec3f & max = bbox.getMax ();
App::DocumentObjectGroup* group = App::DocumentObjectGroup::getGroupOfObject(this->getObject()); 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<App::DocumentObject *> objs; std::vector<App::DocumentObject *> objs;
if(group) // Probe body first
objs = group->getObjectsOfType(Part::Feature::getClassTypeId()); PartDesign::Body* body = PartDesign::Body::findBodyOf ( this->getObject() );
else if (body) {
objs = this->getObject()->getDocument()->getObjectsOfType(Part::Feature::getClassTypeId()); objs = body->getFullModel ();
} else {
// Probe if we belongs to some group
App::DocumentObjectGroup* group = App::DocumentObjectGroup::getGroupOfObject ( this->getObject () );
for(App::DocumentObject* obj: objs){ if(group) {
Part::Feature* feat = static_cast<Part::Feature*>(obj); objs = group->getObjects ();
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(feat); } else {
if (vp->isVisible()){ // Fallback to whole document
Base::BoundBox3d bbf = feat->Shape.getBoundingBox(); objs = this->getObject ()->getDocument ()->getObjects ();
if (bbf.CalcDiagonalLength() < Precision::Infinite()) }
bbox.Add(bbf);
} }
} Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(this->getActiveView())->getViewer();
if (bbox.CalcDiagonalLength() < Precision::Confusion()){ SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion());
bbox.Add(Base::Vector3d(-10.0,-10.0,-10.0)); SbBox3f bbox = getRelevantBoundBox (bboxAction, objs);
bbox.Add(Base::Vector3d(10.0,10.0,10.0));
if ( bbox.getVolume () < Precision::Confusion() ) {
bbox.extendBy ( SbVec3f (-10.0,-10.0,-10.0) );
bbox.extendBy ( SbVec3f ( 10.0, 10.0, 10.0) );
} }
}
bbox.Enlarge(0.1 * bbox.CalcDiagonalLength());
return bbox; return bbox;
} }
SbBox3f ViewProviderDatum::getRelevantBoundBox (
SoGetBoundingBoxAction &bboxAction, const std::vector <App::DocumentObject *> &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<Part::Datum *> ( 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;
}

View File

@ -27,6 +27,9 @@
#include "Gui/ViewProviderGeometryObject.h" #include "Gui/ViewProviderGeometryObject.h"
#include <Base/BoundBox.h> #include <Base/BoundBox.h>
class SbBox3f;
class SoGetBoundingBoxAction;
namespace PartDesignGui { namespace PartDesignGui {
class PartDesignGuiExport ViewProviderDatum : public Gui::ViewProviderGeometryObject class PartDesignGuiExport ViewProviderDatum : public Gui::ViewProviderGeometryObject
@ -57,26 +60,49 @@ public:
virtual std::string getElement(const SoDetail *) const; virtual std::string getElement(const SoDetail *) const;
virtual SoDetail* getDetail(const char*) 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) /// The datum type (Plane, Line or Point)
// TODO remove this atribute (2015-09-08, Fat-Zer)
QString datumType; 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 <App::DocumentObject *> &objs);
protected: protected:
void onChanged(const App::Property* prop); void onChanged(const App::Property* prop);
virtual bool setEdit(int ModNum); virtual bool setEdit(int ModNum);
virtual void unsetEdit(int ModNum); virtual void unsetEdit(int ModNum);
//
/** /**
* @brief getRelevantExtents computes the bounding box of the objects * Gueses the context this datum belongs to and returns apropriate bounding box of all
* relevant to the datum feature, which is intended to be used for * visiable content of the feature
* 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 * Currently known contexts are:
* all visible shapes of a part, if in a part but not in a body. Bounding * - PartDesign::Body
* box of all visible Part::Feature-derived objects if just in a document. * - App::DocumentObjectGroup (App::Part as well as subclass)
* This behavior is subject to change. * - Whole document
*/ */
virtual Base::BoundBox3d getRelevantExtents(); SbBox3f getRelevantBoundBox() const;
protected: protected:
SoSeparator* pShapeSep; SoSeparator* pShapeSep;

View File

@ -95,14 +95,20 @@ ViewProviderDatumCoordinateSystem::~ViewProviderDatumCoordinateSystem()
void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop) void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop)
{ {
if (strcmp(prop->getName(),"Placement") == 0) { 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 base(0,0,0);
Base::Vector3d dir(0,0,1); Base::Vector3d dir(0,0,1);
Base::Vector3d x, y, z; Base::Vector3d x, y, z;
getPointForDirection(Base::Vector3d(1,0,0), x); getPointForDirection(Base::Vector3d(1,0,0), bbox, x);
getPointForDirection(Base::Vector3d(0,1,0), y); getPointForDirection(Base::Vector3d(0,1,0), bbox, y);
getPointForDirection(Base::Vector3d(0,0,1), z); getPointForDirection(Base::Vector3d(0,0,1), bbox, z);
//normalize all to equal lengths //normalize all to equal lengths
Base::Vector3d axis = (x.Sqr() > y.Sqr()) ? x : y; Base::Vector3d axis = (x.Sqr() > y.Sqr()) ? x : y;
@ -179,10 +185,7 @@ void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop)
} }
} }
ViewProviderDatum::updateData(prop); void ViewProviderDatumCoordinateSystem::getPointForDirection(Base::Vector3d dir, const Base::BoundBox3d& in_bbox, Base::Vector3d& p) {
}
void ViewProviderDatumCoordinateSystem::getPointForDirection(Base::Vector3d dir, Base::Vector3d& p) {
// Gets called whenever a property of the attached object changes // Gets called whenever a property of the attached object changes
PartDesign::CoordinateSystem* pcDatum = static_cast<PartDesign::CoordinateSystem*>(this->getObject()); PartDesign::CoordinateSystem* pcDatum = static_cast<PartDesign::CoordinateSystem*>(this->getObject());
@ -194,7 +197,7 @@ void ViewProviderDatumCoordinateSystem::getPointForDirection(Base::Vector3d dir,
PartDesign::Body* body = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(this->getObject())); PartDesign::Body* body = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(this->getObject()));
if (body == NULL) if (body == NULL)
return; return;
Base::BoundBox3d bbox = body->getBoundBox(); Base::BoundBox3d bbox = in_bbox;
bbox = bbox.Transformed(plm.toMatrix()); bbox = bbox.Transformed(plm.toMatrix());
bbox.Enlarge(0.1 * bbox.CalcDiagonalLength()); bbox.Enlarge(0.1 * bbox.CalcDiagonalLength());
if (bbox.IsInBox(base)) { if (bbox.IsInBox(base)) {

View File

@ -43,8 +43,9 @@ public:
virtual void updateData(const App::Property*); virtual void updateData(const App::Property*);
virtual void setExtents (Base::BoundBox3d bbox);
private: 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; SoTranslation *transX, *transY, *transZ;
SoFont* font; SoFont* font;

View File

@ -54,7 +54,7 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumLine,PartDesignGui::ViewProvider
ViewProviderDatumLine::ViewProviderDatumLine() ViewProviderDatumLine::ViewProviderDatumLine()
{ {
sPixmap = "PartDesign_Line.svg"; sPixmap = "PartDesign_Line.svg";
// TODO Let the base class handle material (2015-09-07, Fat-Zer)
SoMaterial* material = new SoMaterial(); SoMaterial* material = new SoMaterial();
material->diffuseColor.setValue(0.9f, 0.9f, 0.13f); material->diffuseColor.setValue(0.9f, 0.9f, 0.13f);
material->transparency.setValue(0.2f); material->transparency.setValue(0.2f);
@ -72,29 +72,38 @@ void ViewProviderDatumLine::updateData(const App::Property* prop)
PartDesign::Line* pcDatum = static_cast<PartDesign::Line*>(this->getObject()); PartDesign::Line* pcDatum = static_cast<PartDesign::Line*>(this->getObject());
if (strcmp(prop->getName(),"Placement") == 0) { if (strcmp(prop->getName(),"Placement") == 0) {
updateExtents ();
}
ViewProviderDatum::updateData(prop);
}
void ViewProviderDatumLine::setExtents (Base::BoundBox3d bbox) {
PartDesign::Line* pcDatum = static_cast<PartDesign::Line*>(this->getObject());
Base::Placement plm = pcDatum->Placement.getValue(); Base::Placement plm = pcDatum->Placement.getValue();
plm.invert(); plm.invert();
Base::Vector3d base(0,0,0); Base::Vector3d base(0,0,0);
Base::Vector3d dir(0,0,1); Base::Vector3d dir(0,0,1);
// Get limits of the line from bounding box of the body // TODO transform point rather the bbox (2015-09-07, Fat-Zer)
Base::BoundBox3d bbox = this->getRelevantExtents(); Base::BoundBox3d my_bbox = bbox.Transformed(plm.toMatrix());
bbox = bbox.Transformed(plm.toMatrix());
Base::Vector3d p1, p2; Base::Vector3d p1, p2;
if (bbox.IsInBox(base)) { if (my_bbox.IsInBox(base)) {
bbox.IntersectionPoint(base, dir, p1, Precision::Confusion()); my_bbox.IntersectionPoint(base, dir, p1, Precision::Confusion());
bbox.IntersectionPoint(base, -dir, p2, Precision::Confusion()); my_bbox.IntersectionPoint(base, -dir, p2, Precision::Confusion());
} else { } else {
bbox.IntersectWithLine(base, dir, p1, p2); my_bbox.IntersectWithLine(base, dir, p1, p2);
if ((p1 == Base::Vector3d(0,0,0)) && (p2 == Base::Vector3d(0,0,0))) if ((p1 == Base::Vector3d(0,0,0)) && (p2 == Base::Vector3d(0,0,0)))
bbox.IntersectWithLine(base, -dir, p1, p2); my_bbox.IntersectWithLine(base, -dir, p1, p2);
} }
// Display the line // Display the line
PartGui::SoBrepEdgeSet* lineSet; PartGui::SoBrepEdgeSet* lineSet;
SoCoordinate3* coord; SoCoordinate3* coord;
// TODO Move initialization to the attach() (2015-09-07, Fat-Zer)
if (pShapeSep->getNumChildren() == 1) { if (pShapeSep->getNumChildren() == 1) {
coord = new SoCoordinate3(); coord = new SoCoordinate3();
coord->point.setNum(2); coord->point.setNum(2);
@ -112,7 +121,3 @@ void ViewProviderDatumLine::updateData(const App::Property* prop)
coord->point.set1Value(1, p2.x, p2.y, p2.z); coord->point.set1Value(1, p2.x, p2.y, p2.z);
} }
} }
ViewProviderDatum::updateData(prop);
}

View File

@ -40,6 +40,7 @@ public:
virtual void updateData(const App::Property*); virtual void updateData(const App::Property*);
virtual void setExtents (Base::BoundBox3d bbox);
}; };
} // namespace PartDesignGui } // namespace PartDesignGui

View File

@ -55,7 +55,7 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumPlane,PartDesignGui::ViewProvide
ViewProviderDatumPlane::ViewProviderDatumPlane() ViewProviderDatumPlane::ViewProviderDatumPlane()
{ {
sPixmap = "PartDesign_Plane.svg"; sPixmap = "PartDesign_Plane.svg";
// TODO Use general material object (2015-09-07, Fat-Zer)
SoMaterial* material = new SoMaterial(); SoMaterial* material = new SoMaterial();
material->diffuseColor.setValue(0.9f, 0.9f, 0.13f); material->diffuseColor.setValue(0.9f, 0.9f, 0.13f);
material->transparency.setValue(0.5f); material->transparency.setValue(0.5f);
@ -73,13 +73,23 @@ void ViewProviderDatumPlane::updateData(const App::Property* prop)
PartDesign::Plane* pcDatum = static_cast<PartDesign::Plane*>(this->getObject()); PartDesign::Plane* pcDatum = static_cast<PartDesign::Plane*>(this->getObject());
if (strcmp(prop->getName(),"Placement") == 0) { if (strcmp(prop->getName(),"Placement") == 0) {
updateExtents ();
}
ViewProviderDatum::updateData(prop);
}
void ViewProviderDatumPlane::setExtents (Base::BoundBox3d bbox) {
PartDesign::Plane* pcDatum = static_cast<PartDesign::Plane*>(this->getObject());
Base::Placement plm = pcDatum->Placement.getValue(); Base::Placement plm = pcDatum->Placement.getValue();
plm.invert(); plm.invert();
Base::Vector3d base(0,0,0); Base::Vector3d base(0,0,0);
Base::Vector3d normal(0,0,1); Base::Vector3d normal(0,0,1);
// Get limits of the plane from bounding box of the body // Get limits of the plane from bounding box of the body
Base::BoundBox3d bbox = this->getRelevantExtents();
bbox = bbox.Transformed(plm.toMatrix()); bbox = bbox.Transformed(plm.toMatrix());
double dlength = bbox.CalcDiagonalLength(); double dlength = bbox.CalcDiagonalLength();
if (dlength < Precision::Confusion()) if (dlength < Precision::Confusion())
@ -248,7 +258,3 @@ void ViewProviderDatumPlane::updateData(const App::Property* prop)
} }
} }
ViewProviderDatum::updateData(prop);
}

View File

@ -40,6 +40,7 @@ public:
virtual void updateData(const App::Property*); virtual void updateData(const App::Property*);
void setExtents (Base::BoundBox3d bbox);
}; };
} // namespace PartDesignGui } // namespace PartDesignGui

View File

@ -66,6 +66,7 @@ ViewProviderDatumPoint::~ViewProviderDatumPoint()
void ViewProviderDatumPoint::updateData(const App::Property* prop) void ViewProviderDatumPoint::updateData(const App::Property* prop)
{ {
// TODO Review this (2015-09-07, Fat-Zer)
if (strcmp(prop->getName(),"Placement") == 0) { 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 // The only reason to do this is to display the point in the correct position after loading the document
SoMarkerSet* marker = static_cast<SoMarkerSet*>(pShapeSep->getChild(1)); SoMarkerSet* marker = static_cast<SoMarkerSet*>(pShapeSep->getChild(1));

View File

@ -40,6 +40,7 @@ public:
virtual void updateData(const App::Property*); virtual void updateData(const App::Property*);
// Note: don't overload setExtents () here because point doesn't really depends on it
}; };
} // namespace PartDesignGui } // namespace PartDesignGui