PartDesign/Gui: add origin sizing and rework datums sizing
This commit is contained in:
parent
56823eeb9d
commit
26fb01b429
|
@ -59,6 +59,16 @@ public:
|
|||
*/
|
||||
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
|
||||
/// Remove the feature from the body
|
||||
virtual void removeFeature(App::DocumentObject* feature){}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
||||
if(connection.connected())
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -45,7 +45,6 @@ public:
|
|||
return "PartDesignGui::ViewProviderDatumLine";
|
||||
}
|
||||
|
||||
Base::Vector3d getBasePoint() const;
|
||||
Base::Vector3d getDirection() const;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -43,7 +43,6 @@ public:
|
|||
return "PartDesignGui::ViewProviderDatumPlane";
|
||||
}
|
||||
|
||||
Base::Vector3d getBasePoint();
|
||||
Base::Vector3d getNormal();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -24,16 +24,21 @@
|
|||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <algorithm>
|
||||
# include <Inventor/nodes/SoGroup.h>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/actions/SoGetBoundingBoxAction.h>
|
||||
# include <Inventor/SbBox3d.h>
|
||||
# include <Precision.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <App/Part.h>
|
||||
#include <App/Origin.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.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/FeatureSketchBased.h>
|
||||
|
@ -42,6 +47,7 @@
|
|||
#include <Mod/PartDesign/App/DatumPlane.h>
|
||||
#include <Mod/PartDesign/App/DatumCS.h>
|
||||
|
||||
#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<App::Part*>(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<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)", 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<App::DocumentObject*> ViewProviderBody::claimChildren3D(void)const
|
|||
|
||||
std::vector<App::DocumentObject*> 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<std::string> &) {
|
|||
|
||||
void ViewProviderBody::updateData(const App::Property* prop)
|
||||
{
|
||||
|
||||
PartDesign::Body* body = static_cast<PartDesign::Body*>(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<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);
|
||||
PartGui::ViewProviderPart::updateData(prop);
|
||||
}
|
||||
|
||||
if (plm != NULL) {
|
||||
Gui::ViewProviderDocumentObject* vp = dynamic_cast<Gui::ViewProviderDocumentObject*>(Gui::Application::Instance->getViewProvider(*f));
|
||||
if (vp != NULL)
|
||||
vp->updateData(plm);
|
||||
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 () );
|
||||
}
|
||||
}
|
||||
|
||||
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 <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 );
|
||||
}
|
||||
|
|
|
@ -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<std::string> &);
|
||||
|
||||
/// 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();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
# include <QMessageBox>
|
||||
# include <QAction>
|
||||
# include <QMenu>
|
||||
# include <Inventor/actions/SoGetBoundingBoxAction.h>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoPickStyle.h>
|
||||
# include <Inventor/nodes/SoShapeHints.h>
|
||||
|
@ -52,10 +53,13 @@
|
|||
#endif
|
||||
|
||||
#include <App/DocumentObjectGroup.h>
|
||||
#include <App/GeoFeatureGroup.h>
|
||||
#include <Gui/Control.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/MDIView.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
|
||||
#include <Mod/PartDesign/App/DatumPoint.h>
|
||||
#include <Mod/PartDesign/App/DatumLine.h>
|
||||
|
@ -64,6 +68,7 @@
|
|||
#include <Mod/PartDesign/App/DatumCS.h>
|
||||
|
||||
#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<PartDesign::Body*>(Part::BodyBase::findBodyOf(this->getObject()));
|
||||
if (body != NULL)
|
||||
bbox = body->getBoundBox();
|
||||
else {
|
||||
App::DocumentObjectGroup* group = App::DocumentObjectGroup::getGroupOfObject(this->getObject());
|
||||
std::vector<App::DocumentObject*> 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<Part::Feature*>(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<App::DocumentObject *> 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<Gui::View3DInventor*>(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 <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;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include "Gui/ViewProviderGeometryObject.h"
|
||||
#include <Base/BoundBox.h>
|
||||
|
||||
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 <App::DocumentObject *> &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;
|
||||
|
|
|
@ -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<SoCoordinate3*>(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<PartDesign::CoordinateSystem*>(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<PartDesign::Body*>(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)) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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<PartDesign::Line*>(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<SoCoordinate3*>(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<PartDesign::Line*>(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<SoCoordinate3*>(pShapeSep->getChild(1));
|
||||
coord->point.set1Value(0, p1.x, p1.y, p1.z);
|
||||
coord->point.set1Value(1, p2.x, p2.y, p2.z);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
|
||||
virtual void updateData(const App::Property*);
|
||||
|
||||
virtual void setExtents (Base::BoundBox3d bbox);
|
||||
};
|
||||
|
||||
} // namespace PartDesignGui
|
||||
|
|
|
@ -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<PartDesign::Plane*>(this->getObject());
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
|
||||
virtual void updateData(const App::Property*);
|
||||
|
||||
void setExtents (Base::BoundBox3d bbox);
|
||||
};
|
||||
|
||||
} // namespace PartDesignGui
|
||||
|
|
|
@ -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<SoMarkerSet*>(pShapeSep->getChild(1));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user