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;
/// 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){}

View File

@ -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();
}

View File

@ -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();

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() {
if(connection.connected())

View File

@ -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;

View File

@ -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();

View File

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

View File

@ -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();

View File

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

View File

@ -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 );
}

View File

@ -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();
};

View File

@ -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;
}

View File

@ -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;

View File

@ -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)) {

View File

@ -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;
};

View File

@ -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);
}
}

View File

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

View File

@ -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);
}

View File

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

View File

@ -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));

View File

@ -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