Gui: Placement/DatumCS view provider changes
* Add always zoom invariant and always on top rendering to ViewProviderDatumCS * Add a new utility class AxisOrigin for more efficient axis rendering. Also exposed to python. * Change ViewProviderPlacement to use AxisOrigin for rendering. A single instance of AxisOrigin is shared by all ViewProviderPlacement. Selection context is used to distinguish among different instances.
This commit is contained in:
@@ -1862,6 +1862,7 @@ void Application::initTypes(void)
|
||||
App ::MaterialObjectPython ::init();
|
||||
App ::TextDocument ::init();
|
||||
App ::Placement ::init();
|
||||
App ::PlacementPython ::init();
|
||||
App ::OriginFeature ::init();
|
||||
App ::Plane ::init();
|
||||
App ::Line ::init();
|
||||
|
||||
@@ -51,6 +51,14 @@ Placement::~Placement(void)
|
||||
|
||||
|
||||
|
||||
// Python feature ---------------------------------------------------------
|
||||
namespace App {
|
||||
PROPERTY_SOURCE_TEMPLATE(App::PlacementPython, App::Placement)
|
||||
template<> const char* App::PlacementPython::getViewProviderName(void) const {
|
||||
return "Gui::ViewProviderPlacementPython";
|
||||
}
|
||||
template class AppExport FeaturePythonT<App::Placement>;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <Base/Placement.h>
|
||||
|
||||
#include "FeaturePython.h"
|
||||
#include "GeoFeature.h"
|
||||
#include "PropertyGeo.h"
|
||||
|
||||
@@ -66,6 +67,7 @@ public:
|
||||
|
||||
|
||||
};
|
||||
typedef App::FeaturePythonT<App::Placement> PlacementPython;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
#include "ViewProviderGroupExtension.h"
|
||||
#include "ViewProviderLink.h"
|
||||
#include "LinkViewPy.h"
|
||||
#include "AxisOriginPy.h"
|
||||
|
||||
#include "Language/Translator.h"
|
||||
#include "TaskView/TaskView.h"
|
||||
@@ -403,7 +404,9 @@ Application::Application(bool GUIenabled)
|
||||
Gui::TaskView::ControlPy::init_type();
|
||||
Py::Module(module).setAttr(std::string("Control"),
|
||||
Py::Object(Gui::TaskView::ControlPy::getInstance(), true));
|
||||
|
||||
Base::Interpreter().addType(&LinkViewPy::Type,module,"LinkView");
|
||||
Base::Interpreter().addType(&AxisOriginPy::Type,module,"AxisOrigin");
|
||||
}
|
||||
|
||||
Base::PyGILStateLocker lock;
|
||||
@@ -1674,6 +1677,7 @@ void Application::initTypes(void)
|
||||
Gui::ViewProviderPythonFeature ::init();
|
||||
Gui::ViewProviderPythonGeometry ::init();
|
||||
Gui::ViewProviderPlacement ::init();
|
||||
Gui::ViewProviderPlacementPython ::init();
|
||||
Gui::ViewProviderOriginFeature ::init();
|
||||
Gui::ViewProviderPlane ::init();
|
||||
Gui::ViewProviderLine ::init();
|
||||
@@ -1689,6 +1693,7 @@ void Application::initTypes(void)
|
||||
Gui::LinkView ::init();
|
||||
Gui::ViewProviderLink ::init();
|
||||
Gui::ViewProviderLinkPython ::init();
|
||||
Gui::AxisOrigin ::init();
|
||||
|
||||
// Workbench
|
||||
Gui::Workbench ::init();
|
||||
|
||||
211
src/Gui/AxisOrigin.cpp
Normal file
211
src/Gui/AxisOrigin.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2019 Zheng, Lei (realthunder) <realthunder.dev@gmail.com>*
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoSwitch.h>
|
||||
# include <Inventor/SoPickedPoint.h>
|
||||
# include <Inventor/nodes/SoMaterial.h>
|
||||
# include <Inventor/nodes/SoMaterialBinding.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/nodes/SoIndexedLineSet.h>
|
||||
# include <Inventor/nodes/SoIndexedPointSet.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/SoFullPath.h>
|
||||
#endif
|
||||
|
||||
#include "Inventor/SoAutoZoomTranslation.h"
|
||||
#include "SoFCSelection.h"
|
||||
#include "SoFCUnifiedSelection.h"
|
||||
#include "AxisOrigin.h"
|
||||
|
||||
using namespace Gui;
|
||||
|
||||
TYPESYSTEM_SOURCE(Gui::AxisOrigin,Base::BaseClass);
|
||||
|
||||
AxisOrigin::AxisOrigin()
|
||||
:size(6),pSize(4),dist(2),scale(1),lineSize(2),pointSize(4)
|
||||
{
|
||||
}
|
||||
|
||||
SoGroup *AxisOrigin::getNode() {
|
||||
if(node)
|
||||
return node;
|
||||
|
||||
node.reset(new SoGroup);
|
||||
auto pMat = new SoMaterial();
|
||||
|
||||
const SbVec3f verts[13] =
|
||||
{
|
||||
SbVec3f(0,0,0), SbVec3f(size,0,0),
|
||||
SbVec3f(0,size,0), SbVec3f(0,0,size),
|
||||
SbVec3f(dist,dist,0), SbVec3f(dist,pSize,0), SbVec3f(pSize,dist,0), // XY Plane
|
||||
SbVec3f(dist,0,dist), SbVec3f(dist,0,pSize), SbVec3f(pSize,0,dist), // XY Plane
|
||||
SbVec3f(0,dist,dist), SbVec3f(0,pSize,dist), SbVec3f(0,dist,pSize) // XY Plane
|
||||
};
|
||||
|
||||
// indexes used to create the edges
|
||||
const int32_t lines[21] =
|
||||
{
|
||||
0,1,-1,
|
||||
0,2,-1,
|
||||
0,3,-1,
|
||||
5,4,6,-1,
|
||||
8,7,9,-1,
|
||||
11,10,12,-1
|
||||
};
|
||||
|
||||
pMat->diffuseColor.setNum(3);
|
||||
pMat->diffuseColor.set1Value(0, SbColor(1.0f, 0.2f, 0.2f));
|
||||
pMat->diffuseColor.set1Value(1, SbColor(0.2f, 0.6f, 0.2f));
|
||||
pMat->diffuseColor.set1Value(2, SbColor(0.2f, 0.2f, 1.0f));
|
||||
pMat->diffuseColor.set1Value(4, SbColor(0.8f, 0.8f, 0.8f));
|
||||
|
||||
auto pCoords = new SoCoordinate3();
|
||||
pCoords->point.setNum(3);
|
||||
pCoords->point.setValues(0, 13, verts);
|
||||
|
||||
SoAutoZoomTranslation *zoom = new SoAutoZoomTranslation;
|
||||
zoom->scaleFactor = scale;
|
||||
|
||||
SoDrawStyle* style = new SoDrawStyle();
|
||||
style->lineWidth = lineSize;
|
||||
style->pointSize = pointSize;
|
||||
|
||||
SoMaterialBinding* matBinding = new SoMaterialBinding;
|
||||
matBinding->value = SoMaterialBinding::PER_FACE_INDEXED;
|
||||
|
||||
node->addChild(zoom);
|
||||
node->addChild(style);
|
||||
node->addChild(matBinding);
|
||||
node->addChild(pMat);
|
||||
node->addChild(pCoords);
|
||||
|
||||
#define CREATE_AXIS(_type,_key,_count,_offset,_mat) do{\
|
||||
const char *label=_key;\
|
||||
if(labels.size()){\
|
||||
auto iter = labels.find(_key);\
|
||||
if(iter == labels.end())\
|
||||
break;\
|
||||
else if(iter->second.size())\
|
||||
label = iter->second.c_str();\
|
||||
}\
|
||||
auto pAxis = new SoFCSelection;\
|
||||
pAxis->applySettings();\
|
||||
pAxis->style = SoFCSelection::EMISSIVE_DIFFUSE;\
|
||||
pAxis->subElementName = label;\
|
||||
nodeMap[label].reset(pAxis);\
|
||||
node->addChild(pAxis);\
|
||||
auto _type = new SoIndexed##_type##Set;\
|
||||
pAxis->addChild(_type);\
|
||||
_type->coordIndex.setNum(_count);\
|
||||
_type->coordIndex.setValues(0,_count,lines+_offset);\
|
||||
_type->materialIndex.setValue(_mat);\
|
||||
}while(0)
|
||||
|
||||
CREATE_AXIS(Point,"O",1,0,4);
|
||||
CREATE_AXIS(Line,"X",3,0,0);
|
||||
CREATE_AXIS(Line,"Y",3,3,1);
|
||||
CREATE_AXIS(Line,"Z",3,6,2);
|
||||
CREATE_AXIS(Line,"XY",4,9,2);
|
||||
CREATE_AXIS(Line,"XZ",4,13,1);
|
||||
CREATE_AXIS(Line,"YZ",4,17,0);
|
||||
return node;
|
||||
}
|
||||
|
||||
bool AxisOrigin::getElementPicked(const SoPickedPoint *pp, std::string &subname) const {
|
||||
SoPath *path = pp->getPath();
|
||||
int length = path->getLength();
|
||||
for(int i=0;i<length;++i) {
|
||||
auto node = path->getNodeFromTail(i);
|
||||
if(node->isOfType(SoFCSelection::getClassTypeId())) {
|
||||
subname = static_cast<SoFCSelection*>(node)->subElementName.getValue().getString();
|
||||
return true;
|
||||
} else if(node->isOfType(SoFCSelectionRoot::getClassTypeId()))
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AxisOrigin::getDetailPath(const char *subname, SoFullPath *pPath, SoDetail *&) const {
|
||||
if(!node)
|
||||
return false;
|
||||
if(!subname || !subname[0])
|
||||
return true;
|
||||
|
||||
auto it = nodeMap.find(subname);
|
||||
if(it == nodeMap.end())
|
||||
return false;
|
||||
pPath->append(node);
|
||||
pPath->append(it->second);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AxisOrigin::setLineWidth(float size) {
|
||||
if(size!=lineSize) {
|
||||
node.reset();
|
||||
nodeMap.clear();
|
||||
lineSize = size;
|
||||
}
|
||||
}
|
||||
|
||||
void AxisOrigin::setPointSize(float size) {
|
||||
if(pointSize!=size) {
|
||||
pointSize = size;
|
||||
node.reset();
|
||||
nodeMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void AxisOrigin::setAxisLength(float size) {
|
||||
if(this->size!=size) {
|
||||
this->size = size;
|
||||
node.reset();
|
||||
nodeMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void AxisOrigin::setPlane(float size, float dist) {
|
||||
if(pSize!=size || this->dist!=dist) {
|
||||
pSize = size;
|
||||
this->dist = dist;
|
||||
node.reset();
|
||||
nodeMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void AxisOrigin::setScale(float scale) {
|
||||
if(this->scale!=scale) {
|
||||
this->scale = scale;
|
||||
node.reset();
|
||||
nodeMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void AxisOrigin::setLabels(const std::map<std::string,std::string> &labels) {
|
||||
this->labels = labels;
|
||||
node.reset();
|
||||
nodeMap.clear();
|
||||
}
|
||||
109
src/Gui/AxisOrigin.h
Normal file
109
src/Gui/AxisOrigin.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2019 Zheng, Lei (realthunder) <realthunder.dev@gmail.com>*
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef GUI_AxisOrigin_H
|
||||
#define GUI_AxisOrigin_H
|
||||
|
||||
#include "ViewProvider.h"
|
||||
|
||||
namespace Gui {
|
||||
|
||||
/// A class to create a Coin3D node representation of an coordinate system
|
||||
class GuiExport AxisOrigin : public Base::BaseClass {
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
AxisOrigin();
|
||||
|
||||
/// Set axis line width
|
||||
void setLineWidth(float size);
|
||||
|
||||
/// Get axis line width
|
||||
float getLineWidth() const { return lineSize; }
|
||||
|
||||
/// Set origin point size
|
||||
void setPointSize(float size);
|
||||
|
||||
/// Get origin point size
|
||||
float getPointSize() const { return pointSize; }
|
||||
|
||||
/// Set the axis line length
|
||||
void setAxisLength(float size);
|
||||
|
||||
/// Get axis base line length
|
||||
float getAxisLength() const { return size; }
|
||||
|
||||
/// Set the origin plane size and distance from the axis
|
||||
void setPlane(float size, float dist);
|
||||
|
||||
/// Get the origin plane size and distance from the axis
|
||||
std::pair<float,float> getPlane() const {return std::make_pair(pSize,dist);}
|
||||
|
||||
/// Set the auto scale factor, 0 to disable it
|
||||
void setScale(float scale);
|
||||
|
||||
/// Get the auto scale factor
|
||||
float getScale() const { return scale; }
|
||||
|
||||
/** Set customized names for axis components
|
||||
*
|
||||
* @param labels: the input names. Avaiable keys are, O: origin,
|
||||
* X: x axis, Y: y axis, Z: z axis, XY: XY plane,
|
||||
* XZ: XY plane, YZ: YZ plane
|
||||
*
|
||||
* There are default labels for all components. You can also use
|
||||
* this function to choose which components are hidden, by not
|
||||
* include the key in the input labels.
|
||||
*/
|
||||
void setLabels(const std::map<std::string,std::string> &labels);
|
||||
|
||||
/// Obtain the axis component names
|
||||
const std::map<std::string,std::string> &getLabels() const { return labels; }
|
||||
|
||||
/// Obtain the constructed Coin3D representation
|
||||
SoGroup *getNode();
|
||||
|
||||
/** Return the name of picked element
|
||||
* @sa ViewProvider::getElementPicked()
|
||||
*/
|
||||
bool getElementPicked(const SoPickedPoint *pp, std::string &subname) const;
|
||||
|
||||
/** Return the coin path of a named element
|
||||
* @sa ViewProvider::getDetailPath()
|
||||
*/
|
||||
bool getDetailPath(const char *subname, SoFullPath *pPath, SoDetail *&det) const;
|
||||
|
||||
private:
|
||||
float size;
|
||||
float pSize;
|
||||
float dist;
|
||||
float scale;
|
||||
float lineSize;
|
||||
float pointSize;
|
||||
std::map<std::string, std::string> labels;
|
||||
CoinPtr<SoGroup> node;
|
||||
std::map<std::string, CoinPtr<SoNode> > nodeMap;
|
||||
};
|
||||
|
||||
} // namepsace Gui
|
||||
|
||||
#endif //GUI_AxisOrigin_H
|
||||
85
src/Gui/AxisOriginPy.xml
Normal file
85
src/Gui/AxisOriginPy.xml
Normal file
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="BaseClassPy"
|
||||
Name="AxisOriginPy"
|
||||
Twin="AxisOrigin"
|
||||
TwinPointer="AxisOrigin"
|
||||
Include="Gui/AxisOrigin.h"
|
||||
Namespace="Gui"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
FatherNamespace="Base"
|
||||
Constructor="true"
|
||||
Delete="true">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Zheng, Lei" EMail="realthunder.dev@gmail.com" />
|
||||
<UserDocu>Class for creating a Coin3D representation of a coordinate system</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="getElementPicked" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>getElementPicked(pickPoint): return the picked subelement</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getDetailPath" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
getDetailPath(subname,path): return Coin detail and path of an subelement
|
||||
|
||||
subelement: dot separated string reference to the sub element
|
||||
pPath: output coin path leading to the returned element detail
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Attribute Name="AxisLength">
|
||||
<Documentation>
|
||||
<UserDocu>Get/set the axis length</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="AxisLength" Type="Float" />
|
||||
</Attribute>
|
||||
<Attribute Name="LineWidth">
|
||||
<Documentation>
|
||||
<UserDocu>Get/set the axis line width for rendering</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="LineWidth" Type="Float" />
|
||||
</Attribute>
|
||||
<Attribute Name="PointSize">
|
||||
<Documentation>
|
||||
<UserDocu>Get/set the origin point size for rendering</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="PointSize" Type="Float" />
|
||||
</Attribute>
|
||||
<Attribute Name="Scale">
|
||||
<Documentation>
|
||||
<UserDocu>Get/set auto scaling factor, 0 to disable</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Scale" Type="Float" />
|
||||
</Attribute>
|
||||
<Attribute Name="Plane">
|
||||
<Documentation>
|
||||
<UserDocu>Get/set axis plane size and distance to axis line</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Plane" Type="Tuple" />
|
||||
</Attribute>
|
||||
<Attribute Name="Labels">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
Get/set axis component names as a dictionary. Avaiable keys are,
|
||||
'O': origin
|
||||
'X': x axis
|
||||
'Y': y axis
|
||||
'Z': z axis
|
||||
'XY': xy plane
|
||||
'XZ': xz plane
|
||||
'YZ': yz plane
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Labels" Type="Dict" />
|
||||
</Attribute>
|
||||
<Attribute Name="Node" ReadOnly='true'>
|
||||
<Documentation>
|
||||
<UserDocu>Get the Coin3D node</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Node" Type="Object" />
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
170
src/Gui/AxisOriginPyImp.cpp
Normal file
170
src/Gui/AxisOriginPyImp.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2019 Zheng, Lei (realthunder) <realthunder.dev@gmail.com>*
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoGroup.h>
|
||||
# include <Inventor/details/SoDetail.h>
|
||||
# include <Inventor/SoFullPath.h>
|
||||
#endif
|
||||
|
||||
#include "AxisOriginPy.h"
|
||||
#include "AxisOriginPy.cpp"
|
||||
|
||||
using namespace Gui;
|
||||
|
||||
PyObject *AxisOriginPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
{
|
||||
return new AxisOriginPy(new AxisOrigin);
|
||||
}
|
||||
|
||||
int AxisOriginPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// returns a string which represent the object e.g. when printed in python
|
||||
std::string AxisOriginPy::representation(void) const
|
||||
{
|
||||
return "<AxisOrigin>";
|
||||
}
|
||||
|
||||
PyObject* AxisOriginPy::getElementPicked(PyObject* args)
|
||||
{
|
||||
PyObject *obj;
|
||||
if (!PyArg_ParseTuple(args, "O",&obj))
|
||||
return NULL;
|
||||
void *ptr = 0;
|
||||
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "_p_SoPickedPoint", obj, &ptr, 0);
|
||||
SoPickedPoint *pp = reinterpret_cast<SoPickedPoint*>(ptr);
|
||||
if(!pp)
|
||||
throw Base::TypeError("type must be of coin.SoPickedPoint");
|
||||
std::string name;
|
||||
if(!getAxisOriginPtr()->getElementPicked(pp,name))
|
||||
Py_Return;
|
||||
return Py::new_reference_to(Py::String(name));
|
||||
}
|
||||
|
||||
PyObject* AxisOriginPy::getDetailPath(PyObject* args)
|
||||
{
|
||||
const char *sub;
|
||||
PyObject *path;
|
||||
if (!PyArg_ParseTuple(args, "sO",&sub,&path))
|
||||
return NULL;
|
||||
void *ptr = 0;
|
||||
Base::Interpreter().convertSWIGPointerObj("pivy.coin", "_p_SoPath", path, &ptr, 0);
|
||||
SoPath *pPath = reinterpret_cast<SoPath*>(ptr);
|
||||
if(!pPath)
|
||||
throw Base::TypeError("type must be of coin.SoPath");
|
||||
SoDetail *det = 0;
|
||||
if(!getAxisOriginPtr()->getDetailPath(
|
||||
sub,static_cast<SoFullPath*>(pPath),det))
|
||||
{
|
||||
if(det) delete det;
|
||||
Py_Return;
|
||||
}
|
||||
if(!det)
|
||||
return Py::new_reference_to(Py::True());
|
||||
return Base::Interpreter().createSWIGPointerObj("pivy.coin", "_p_SoDetail", (void*)det, 0);
|
||||
}
|
||||
|
||||
Py::Float AxisOriginPy::getAxisLength() const {
|
||||
return Py::Float(getAxisOriginPtr()->getAxisLength());
|
||||
}
|
||||
|
||||
void AxisOriginPy::setAxisLength(Py::Float size) {
|
||||
getAxisOriginPtr()->setAxisLength(size);
|
||||
}
|
||||
|
||||
Py::Float AxisOriginPy::getLineWidth() const {
|
||||
return Py::Float(getAxisOriginPtr()->getLineWidth());
|
||||
}
|
||||
|
||||
void AxisOriginPy::setLineWidth(Py::Float size) {
|
||||
getAxisOriginPtr()->setLineWidth(size);
|
||||
}
|
||||
|
||||
Py::Float AxisOriginPy::getPointSize() const {
|
||||
return Py::Float(getAxisOriginPtr()->getPointSize());
|
||||
}
|
||||
|
||||
void AxisOriginPy::setPointSize(Py::Float size) {
|
||||
getAxisOriginPtr()->setPointSize(size);
|
||||
}
|
||||
|
||||
Py::Float AxisOriginPy::getScale() const {
|
||||
return Py::Float(getAxisOriginPtr()->getScale());
|
||||
}
|
||||
|
||||
void AxisOriginPy::setScale(Py::Float size) {
|
||||
getAxisOriginPtr()->setScale(size);
|
||||
}
|
||||
|
||||
Py::Tuple AxisOriginPy::getPlane() const {
|
||||
auto info = getAxisOriginPtr()->getPlane();
|
||||
Py::Tuple ret(2);
|
||||
ret.setItem(0,Py::Float(info.first));
|
||||
ret.setItem(1,Py::Float(info.second));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AxisOriginPy::setPlane(Py::Tuple tuple) {
|
||||
float s,d;
|
||||
if (!PyArg_ParseTuple(*tuple, "dd",&s,&d))
|
||||
throw Py::Exception();
|
||||
getAxisOriginPtr()->setPlane(s,d);
|
||||
}
|
||||
|
||||
Py::Dict AxisOriginPy::getLabels() const {
|
||||
Py::Dict dict;
|
||||
for(auto &v : getAxisOriginPtr()->getLabels())
|
||||
dict.setItem(Py::String(v.first),Py::String(v.second));
|
||||
return dict;
|
||||
}
|
||||
|
||||
void AxisOriginPy::setLabels(Py::Dict dict) {
|
||||
std::map<std::string,std::string> labels;
|
||||
for(auto it=dict.begin();it!=dict.end();++it) {
|
||||
const auto &value = *it;
|
||||
labels[value.first.as_string()] = Py::Object(value.second).as_string();
|
||||
}
|
||||
getAxisOriginPtr()->setLabels(labels);
|
||||
}
|
||||
|
||||
Py::Object AxisOriginPy::getNode(void) const
|
||||
{
|
||||
SoGroup* node = getAxisOriginPtr()->getNode();
|
||||
PyObject* Ptr = Base::Interpreter().createSWIGPointerObj("pivy.coin","SoGroup *", node, 1);
|
||||
node->ref();
|
||||
return Py::Object(Ptr, true);
|
||||
}
|
||||
|
||||
PyObject *AxisOriginPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AxisOriginPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -212,6 +212,7 @@ generate_from_xml(WorkbenchPy)
|
||||
generate_from_xml(SelectionObjectPy)
|
||||
generate_from_xml(LinkViewPy)
|
||||
generate_from_xml(ViewProviderLinkPy)
|
||||
generate_from_xml(AxisOriginPy)
|
||||
|
||||
generate_from_py(FreeCADGuiInit GuiInitScript.h)
|
||||
|
||||
@@ -225,6 +226,7 @@ SET(FreeCADGui_XML_SRCS
|
||||
DocumentPy.xml
|
||||
LinkViewPy.xml
|
||||
ViewProviderLinkPy.xml
|
||||
AxisOriginPy.xml
|
||||
)
|
||||
SOURCE_GROUP("XML" FILES ${FreeCADApp_XML_SRCS})
|
||||
|
||||
@@ -1001,6 +1003,8 @@ SET(Viewprovider_CPP_SRCS
|
||||
ViewProviderLink.cpp
|
||||
LinkViewPyImp.cpp
|
||||
ViewProviderLinkPyImp.cpp
|
||||
AxisOriginPyImp.cpp
|
||||
AxisOrigin.cpp
|
||||
)
|
||||
SET(Viewprovider_SRCS
|
||||
${Viewprovider_CPP_SRCS}
|
||||
@@ -1032,6 +1036,7 @@ SET(Viewprovider_SRCS
|
||||
ViewProviderMaterialObject.h
|
||||
ViewProviderTextDocument.h
|
||||
ViewProviderLink.h
|
||||
AxisOrigin.h
|
||||
)
|
||||
SOURCE_GROUP("View3D\\Viewprovider" FILES ${Viewprovider_SRCS})
|
||||
|
||||
|
||||
@@ -73,16 +73,20 @@ void SoAutoZoomTranslation::initClass()
|
||||
|
||||
float SoAutoZoomTranslation::getScaleFactor(SoAction* action) const
|
||||
{
|
||||
float scale = scaleFactor.getValue();
|
||||
if(!scale)
|
||||
return 1.0;
|
||||
// Dividing by 5 seems to work well
|
||||
SbViewVolume vv = SoViewVolumeElement::get(action->getState());
|
||||
float aspectRatio = SoViewportRegionElement::get(action->getState()).getViewportAspectRatio();
|
||||
float scale = vv.getWorldToScreenScale(SbVec3f(0.f, 0.f, 0.f), 0.1f) / (5*aspectRatio);
|
||||
scale *= vv.getWorldToScreenScale(SbVec3f(0.f, 0.f, 0.f), 0.1f) / (5*aspectRatio);
|
||||
return scale;
|
||||
}
|
||||
|
||||
SoAutoZoomTranslation::SoAutoZoomTranslation()
|
||||
{
|
||||
SO_NODE_CONSTRUCTOR(SoAutoZoomTranslation);
|
||||
SO_NODE_ADD_FIELD(scaleFactor, (1.0f));
|
||||
//SO_NODE_ADD_FIELD(abPos, (SbVec3f(0.f,0.f,0.f)));
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ public:
|
||||
SoAutoZoomTranslation();
|
||||
//SoSFVec3f abPos;
|
||||
|
||||
SoSFFloat scaleFactor;
|
||||
|
||||
protected:
|
||||
virtual ~SoAutoZoomTranslation() {};
|
||||
virtual void doAction(SoAction * action);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
# include <Inventor/nodes/SoTranslation.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoIndexedLineSet.h>
|
||||
# include <Inventor/nodes/SoIndexedPointSet.h>
|
||||
# include <Inventor/nodes/SoMarkerSet.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
#endif
|
||||
@@ -45,6 +46,7 @@
|
||||
#include <Inventor/details/SoLineDetail.h>
|
||||
#include "ViewProviderPlacement.h"
|
||||
#include "SoFCSelection.h"
|
||||
#include "SoFCUnifiedSelection.h"
|
||||
#include "Application.h"
|
||||
#include "Document.h"
|
||||
#include "View3DInventorViewer.h"
|
||||
@@ -61,63 +63,23 @@ using namespace Gui;
|
||||
|
||||
PROPERTY_SOURCE(Gui::ViewProviderPlacement, Gui::ViewProviderGeometryObject)
|
||||
|
||||
|
||||
ViewProviderPlacement::ViewProviderPlacement()
|
||||
{
|
||||
// Change root node to SoFCSelectionRoot because we share the same
|
||||
// AxisOrigin node for all instances of Placement
|
||||
auto newRoot = new SoFCSelectionRoot(true);
|
||||
for(int i=0;i<pcRoot->getNumChildren();++i)
|
||||
newRoot->addChild(pcRoot->getChild(i));
|
||||
pcRoot->unref();
|
||||
pcRoot = newRoot;
|
||||
pcRoot->ref();
|
||||
sPixmap = "CoordinateSystem";
|
||||
|
||||
pMat = new SoMaterial();
|
||||
pMat->ref();
|
||||
|
||||
const float dist = 2;
|
||||
const float size = 6;
|
||||
const float pSize = 4;
|
||||
|
||||
static const SbVec3f verts[13] =
|
||||
{
|
||||
SbVec3f(0,0,0), SbVec3f(size,0,0),
|
||||
SbVec3f(0,size,0), SbVec3f(0,0,size),
|
||||
SbVec3f(dist,dist,0), SbVec3f(dist,pSize,0), SbVec3f(pSize,dist,0), // XY Plane
|
||||
SbVec3f(dist,0,dist), SbVec3f(dist,0,pSize), SbVec3f(pSize,0,dist), // XY Plane
|
||||
SbVec3f(0,dist,dist), SbVec3f(0,pSize,dist), SbVec3f(0,dist,pSize) // XY Plane
|
||||
};
|
||||
|
||||
// indexes used to create the edges
|
||||
static const int32_t lines[21] =
|
||||
{
|
||||
0,1,-1,
|
||||
0,2,-1,
|
||||
0,3,-1,
|
||||
5,4,6,-1,
|
||||
8,7,9,-1,
|
||||
11,10,12,-1
|
||||
};
|
||||
|
||||
pMat->diffuseColor.setNum(6);
|
||||
pMat->diffuseColor.set1Value(0, SbColor(1.0f, 0.2f, 0.2f));
|
||||
pMat->diffuseColor.set1Value(1, SbColor(0.2f, 1.0f, 0.2f));
|
||||
pMat->diffuseColor.set1Value(2, SbColor(0.2f, 0.2f, 1.0f));
|
||||
|
||||
pMat->diffuseColor.set1Value(3, SbColor(1.0f, 1.0f, 0.8f));
|
||||
pMat->diffuseColor.set1Value(4, SbColor(1.0f, 0.8f, 1.0f));
|
||||
pMat->diffuseColor.set1Value(5, SbColor(0.8f, 1.0f, 1.0f));
|
||||
|
||||
pCoords = new SoCoordinate3();
|
||||
pCoords->ref();
|
||||
pCoords->point.setNum(13);
|
||||
pCoords->point.setValues(0, 13, verts);
|
||||
|
||||
pLines = new SoIndexedLineSet();
|
||||
pLines->ref();
|
||||
pLines->coordIndex.setNum(21);
|
||||
pLines->coordIndex.setValues(0, 21, lines);
|
||||
sPixmap = "view-measurement";
|
||||
OnTopWhenSelected.setValue(1);
|
||||
}
|
||||
|
||||
ViewProviderPlacement::~ViewProviderPlacement()
|
||||
{
|
||||
pCoords->unref();
|
||||
pLines->unref();
|
||||
pMat->unref();
|
||||
}
|
||||
|
||||
void ViewProviderPlacement::onChanged(const App::Property* prop)
|
||||
@@ -140,29 +102,24 @@ void ViewProviderPlacement::setDisplayMode(const char* ModeName)
|
||||
ViewProviderGeometryObject::setDisplayMode(ModeName);
|
||||
}
|
||||
|
||||
static std::unique_ptr<AxisOrigin> Axis;
|
||||
|
||||
void ViewProviderPlacement::attach(App::DocumentObject* pcObject)
|
||||
{
|
||||
ViewProviderGeometryObject::attach(pcObject);
|
||||
|
||||
SoAnnotation *lineSep = new SoAnnotation();
|
||||
|
||||
|
||||
SoAutoZoomTranslation *zoom = new SoAutoZoomTranslation;
|
||||
|
||||
SoDrawStyle* style = new SoDrawStyle();
|
||||
style->lineWidth = 2.0f;
|
||||
|
||||
SoMaterialBinding* matBinding = new SoMaterialBinding;
|
||||
matBinding->value = SoMaterialBinding::PER_FACE;
|
||||
|
||||
lineSep->addChild(zoom);
|
||||
lineSep->addChild(style);
|
||||
lineSep->addChild(matBinding);
|
||||
lineSep->addChild(pMat);
|
||||
lineSep->addChild(pCoords);
|
||||
lineSep->addChild(pLines);
|
||||
|
||||
addDisplayMaskMode(lineSep, "Base");
|
||||
if(!Axis) {
|
||||
Axis.reset(new AxisOrigin);
|
||||
std::map<std::string,std::string> labels;
|
||||
labels["O"] = "Origin";
|
||||
labels["X"] = "X-Axis";
|
||||
labels["Y"] = "Y-Axis";
|
||||
labels["Z"] = "Z-Axis";
|
||||
labels["XY"] = "XY-Plane";
|
||||
labels["XZ"] = "XZ-Plane";
|
||||
labels["YZ"] = "YZ-Plane";
|
||||
Axis->setLabels(labels);
|
||||
}
|
||||
addDisplayMaskMode(Axis->getNode(), "Base");
|
||||
}
|
||||
|
||||
void ViewProviderPlacement::updateData(const App::Property* prop)
|
||||
@@ -170,47 +127,27 @@ void ViewProviderPlacement::updateData(const App::Property* prop)
|
||||
ViewProviderGeometryObject::updateData(prop);
|
||||
}
|
||||
|
||||
std::string ViewProviderPlacement::getElement(const SoDetail* detail) const
|
||||
{
|
||||
if (detail) {
|
||||
if (detail->getTypeId() == SoLineDetail::getClassTypeId()) {
|
||||
const SoLineDetail* line_detail = static_cast<const SoLineDetail*>(detail);
|
||||
int edge = line_detail->getLineIndex();
|
||||
switch (edge)
|
||||
{
|
||||
case 0: return std::string("X-Axis");
|
||||
case 1: return std::string("Y-Axis");
|
||||
case 2: return std::string("Z-Axis");
|
||||
case 3: return std::string("XY-Plane");
|
||||
case 4: return std::string("XZ-Plane");
|
||||
case 5: return std::string("YZ-Plane");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::string("");
|
||||
bool ViewProviderPlacement::getElementPicked(const SoPickedPoint *pp, std::string &subname) const {
|
||||
if(!Axis)
|
||||
return false;
|
||||
return Axis->getElementPicked(pp,subname);
|
||||
}
|
||||
|
||||
SoDetail* ViewProviderPlacement::getDetail(const char* subelement) const
|
||||
bool ViewProviderPlacement::getDetailPath(
|
||||
const char *subname, SoFullPath *pPath, bool append, SoDetail *&det) const
|
||||
{
|
||||
SoLineDetail* detail = 0;
|
||||
std::string subelem(subelement);
|
||||
int edge = -1;
|
||||
|
||||
if(subelem == "X-Axis") edge = 0;
|
||||
else if(subelem == "Y-Axis") edge = 1;
|
||||
else if(subelem == "Z-Axis") edge = 2;
|
||||
else if(subelem == "XY-Plane") edge = 3;
|
||||
else if(subelem == "XZ-Plane") edge = 4;
|
||||
else if(subelem == "YZ-Plane") edge = 5;
|
||||
|
||||
if(edge >= 0) {
|
||||
detail = new SoLineDetail();
|
||||
detail->setPartIndex(edge);
|
||||
if(!Axis)
|
||||
return false;
|
||||
int length = pPath->getLength();
|
||||
if(append) {
|
||||
pPath->append(pcRoot);
|
||||
pPath->append(pcModeSwitch);
|
||||
}
|
||||
|
||||
|
||||
return detail;
|
||||
if(!Axis->getDetailPath(subname,pPath,det)) {
|
||||
pPath->truncate(length);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ViewProviderPlacement::isSelectable(void) const
|
||||
@@ -219,4 +156,14 @@ bool ViewProviderPlacement::isSelectable(void) const
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Python feature -----------------------------------------------------------------------
|
||||
|
||||
namespace Gui {
|
||||
/// @cond DOXERR
|
||||
PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderPlacementPython, Gui::ViewProviderPlacement)
|
||||
/// @endcond
|
||||
|
||||
// explicit template instantiation
|
||||
template class GuiExport ViewProviderPythonFeatureT<ViewProviderPlacement>;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
#ifndef GUI_ViewProviderPlacement_H
|
||||
#define GUI_ViewProviderPlacement_H
|
||||
|
||||
#include "AxisOrigin.h"
|
||||
#include "ViewProviderGeometryObject.h"
|
||||
#include "ViewProviderPythonFeature.h"
|
||||
#include <QObject>
|
||||
|
||||
class SoFontStyle;
|
||||
@@ -39,7 +41,6 @@ class SoMaterial;
|
||||
namespace Gui
|
||||
{
|
||||
|
||||
|
||||
class GuiExport ViewProviderPlacement : public ViewProviderGeometryObject
|
||||
{
|
||||
PROPERTY_HEADER(Gui::ViewProviderPlacement);
|
||||
@@ -58,19 +59,17 @@ public:
|
||||
virtual bool useNewSelectionModel(void) const {return true;}
|
||||
/// indicates if the ViewProvider can be selected
|
||||
virtual bool isSelectable(void) const ;
|
||||
/// return a hit element to the selection path or 0
|
||||
virtual std::string getElement(const SoDetail *) const;
|
||||
virtual SoDetail* getDetail(const char*) const;
|
||||
|
||||
virtual bool getElementPicked(const SoPickedPoint *pp, std::string &subname) const override;
|
||||
virtual bool getDetailPath(const char *, SoFullPath *, bool, SoDetail *&) const override;
|
||||
|
||||
protected:
|
||||
void onChanged(const App::Property* prop);
|
||||
|
||||
private:
|
||||
SoCoordinate3 * pCoords;
|
||||
SoMaterial * pMat;
|
||||
SoIndexedLineSet * pLines;
|
||||
};
|
||||
|
||||
typedef ViewProviderPythonFeatureT<ViewProviderPlacement> ViewProviderPlacementPython;
|
||||
|
||||
} //namespace Gui
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoAsciiText.h>
|
||||
# include <Inventor/nodes/SoText2.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/nodes/SoFont.h>
|
||||
@@ -32,8 +32,12 @@
|
||||
# include <Inventor/nodes/SoRotation.h>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoTranslation.h>
|
||||
# include <Inventor/nodes/SoSwitch.h>
|
||||
# include <Inventor/details/SoLineDetail.h>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Gui/Inventor/SoAutoZoomTranslation.h>
|
||||
#include "TaskDatumParameters.h"
|
||||
#include <Mod/Part/Gui/SoBrepEdgeSet.h>
|
||||
|
||||
@@ -43,13 +47,33 @@ using namespace PartDesignGui;
|
||||
|
||||
PROPERTY_SOURCE(PartDesignGui::ViewProviderDatumCoordinateSystem,PartDesignGui::ViewProviderDatum)
|
||||
|
||||
const App::PropertyFloatConstraint::Constraints ZoomConstraint = {0.0,DBL_MAX,0.2};
|
||||
const App::PropertyIntegerConstraint::Constraints FontConstraint = {1,INT_MAX,1};
|
||||
|
||||
ViewProviderDatumCoordinateSystem::ViewProviderDatumCoordinateSystem()
|
||||
{
|
||||
Zoom.setConstraints(&ZoomConstraint);
|
||||
FontSize.setConstraints(&FontConstraint);
|
||||
|
||||
auto hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/PartDesign");
|
||||
auto fontSize = hGrp->GetInt("CoordinateSystemFontSize",10);
|
||||
auto zoom = hGrp->GetFloat("CoordinateSystemZoom",1.0);
|
||||
auto showLabel = hGrp->GetBool("CoordinateSystemShowLabel",false);
|
||||
|
||||
ADD_PROPERTY_TYPE(FontSize, (fontSize), "Datum", App::Prop_None, "");
|
||||
ADD_PROPERTY_TYPE(Zoom, (zoom), "Datum", App::Prop_None, "");
|
||||
ADD_PROPERTY_TYPE(ShowLabel, (showLabel), "Datum", App::Prop_None, "");
|
||||
|
||||
if(hGrp->GetBool("CoordinateSystemSelectOnTop",true))
|
||||
OnTopWhenSelected.setValue(1);
|
||||
|
||||
sPixmap = "PartDesign_CoordinateSystem.svg";
|
||||
|
||||
coord = new SoCoordinate3();
|
||||
coord->ref();
|
||||
font = new SoFont();
|
||||
font->size = FontSize.getValue();
|
||||
font->ref();
|
||||
axisLabelXTrans = new SoTranslation();
|
||||
axisLabelXTrans->ref();
|
||||
@@ -57,6 +81,11 @@ ViewProviderDatumCoordinateSystem::ViewProviderDatumCoordinateSystem()
|
||||
axisLabelXToYTrans->ref();
|
||||
axisLabelYToZTrans = new SoTranslation();
|
||||
axisLabelYToZTrans->ref();
|
||||
|
||||
autoZoom = new Gui::SoAutoZoomTranslation;
|
||||
autoZoom->ref();
|
||||
|
||||
labelSwitch = 0;
|
||||
}
|
||||
|
||||
ViewProviderDatumCoordinateSystem::~ViewProviderDatumCoordinateSystem()
|
||||
@@ -66,6 +95,9 @@ ViewProviderDatumCoordinateSystem::~ViewProviderDatumCoordinateSystem()
|
||||
axisLabelXTrans->unref();
|
||||
axisLabelXToYTrans->unref();
|
||||
axisLabelYToZTrans->unref();
|
||||
if(labelSwitch)
|
||||
labelSwitch->unref();
|
||||
autoZoom->unref();
|
||||
}
|
||||
|
||||
void ViewProviderDatumCoordinateSystem::attach ( App::DocumentObject *obj ) {
|
||||
@@ -75,11 +107,13 @@ void ViewProviderDatumCoordinateSystem::attach ( App::DocumentObject *obj ) {
|
||||
material->diffuseColor.setNum(4);
|
||||
material->diffuseColor.set1Value(0, SbColor(0.f, 0.f, 0.f));
|
||||
material->diffuseColor.set1Value(1, SbColor(1.f, 0.f, 0.f));
|
||||
material->diffuseColor.set1Value(2, SbColor(0.f, 1.f, 0.f));
|
||||
material->diffuseColor.set1Value(2, SbColor(0.f, 0.6f, 0.f));
|
||||
material->diffuseColor.set1Value(3, SbColor(0.f, 0.f, 1.f));
|
||||
SoMaterialBinding* binding = new SoMaterialBinding();
|
||||
binding->value = SoMaterialBinding::PER_FACE_INDEXED;
|
||||
|
||||
autoZoom->scaleFactor.setValue(Zoom.getValue());
|
||||
getShapeRoot ()->addChild(autoZoom);
|
||||
getShapeRoot ()->addChild(binding);
|
||||
getShapeRoot ()->addChild(material);
|
||||
|
||||
@@ -114,55 +148,126 @@ void ViewProviderDatumCoordinateSystem::attach ( App::DocumentObject *obj ) {
|
||||
lineSet->materialIndex.set1Value(2,3);
|
||||
getShapeRoot ()->addChild(lineSet);
|
||||
|
||||
getShapeRoot ()->addChild(font);
|
||||
setupLabels();
|
||||
}
|
||||
|
||||
void ViewProviderDatumCoordinateSystem::setupLabels() {
|
||||
|
||||
if(!ShowLabel.getValue()) {
|
||||
if(labelSwitch)
|
||||
labelSwitch->whichChild = -1;
|
||||
return;
|
||||
}else if(labelSwitch) {
|
||||
labelSwitch->whichChild = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
labelSwitch = new SoSwitch;
|
||||
labelSwitch->ref();
|
||||
|
||||
getShapeRoot ()->addChild(labelSwitch);
|
||||
|
||||
SoGroup *labelGroup = new SoGroup;
|
||||
labelSwitch->addChild(labelGroup);
|
||||
labelSwitch->whichChild = 0;
|
||||
|
||||
labelGroup->addChild(font);
|
||||
|
||||
// Transformation for axis labels are relative so no need in separators
|
||||
getShapeRoot ()->addChild(axisLabelXTrans);
|
||||
SoAsciiText* t = new SoAsciiText();
|
||||
labelGroup->addChild(axisLabelXTrans);
|
||||
auto* t = new SoText2();
|
||||
t->string = "X";
|
||||
getShapeRoot ()->addChild(t);
|
||||
labelGroup->addChild(t);
|
||||
|
||||
getShapeRoot ()->addChild(axisLabelXToYTrans);
|
||||
t = new SoAsciiText();
|
||||
labelGroup->addChild(axisLabelXToYTrans);
|
||||
t = new SoText2();
|
||||
t->string = "Y";
|
||||
getShapeRoot ()->addChild(t);
|
||||
labelGroup->addChild(t);
|
||||
|
||||
getShapeRoot ()->addChild(axisLabelYToZTrans);
|
||||
SoRotation *rot = new SoRotation();
|
||||
rot->rotation = SbRotation(SbVec3f(1,1,1), static_cast<float>(2*M_PI/3));
|
||||
getShapeRoot ()->addChild(rot);
|
||||
t = new SoAsciiText();
|
||||
labelGroup->addChild(axisLabelYToZTrans);
|
||||
t = new SoText2();
|
||||
t->string = "Z";
|
||||
getShapeRoot ()->addChild(t);
|
||||
labelGroup->addChild(t);
|
||||
}
|
||||
|
||||
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::onChanged(const App::Property *prop) {
|
||||
if(getObject()) {
|
||||
if(prop == &ShowLabel)
|
||||
setupLabels();
|
||||
else if(prop == &Zoom) {
|
||||
autoZoom->scaleFactor.setValue(Zoom.getValue());
|
||||
updateExtents ();
|
||||
} else if(prop == &FontSize)
|
||||
font->size = FontSize.getValue();
|
||||
}
|
||||
ViewProviderDatum::onChanged(prop);
|
||||
}
|
||||
|
||||
void ViewProviderDatumCoordinateSystem::setExtents (Base::BoundBox3d bbox) {
|
||||
// Axis length of the CS is 1/3 of maximum bbox dimension, any smarter sizing will make it only worse
|
||||
double axisLength = std::max ( { bbox.LengthX (), bbox.LengthY(), bbox.LengthZ() } );
|
||||
axisLength *= (1 + marginFactor ()) / 3;
|
||||
double axisLength;
|
||||
|
||||
if(Zoom.getValue()) {
|
||||
axisLength = 6 * Zoom.getValue();
|
||||
}else{
|
||||
axisLength = std::max ( { bbox.LengthX (), bbox.LengthY(), bbox.LengthZ() } );
|
||||
axisLength *= (1 + marginFactor ()) / 3;
|
||||
}
|
||||
|
||||
coord->point.set1Value ( 0, 0, 0, 0 );
|
||||
coord->point.set1Value ( 1, axisLength, 0, 0 );
|
||||
coord->point.set1Value ( 2, 0, axisLength, 0 );
|
||||
coord->point.set1Value ( 3, 0, 0, axisLength );
|
||||
|
||||
double fontSz = axisLength / 10.;
|
||||
font->size = fontSz;
|
||||
|
||||
double labelPos = 9./10.*axisLength;
|
||||
double labelOffset = fontSz/8.;
|
||||
double labelPos = axisLength;
|
||||
double labelOffset = 0;
|
||||
|
||||
// offset 1 pixel
|
||||
axisLabelXTrans->translation.setValue ( SbVec3f( labelPos, labelOffset, 0) );
|
||||
axisLabelXToYTrans->translation.setValue ( SbVec3f( -labelPos + labelOffset, labelPos - labelOffset, 0) );
|
||||
axisLabelYToZTrans->translation.setValue ( SbVec3f( -labelOffset, -labelPos + labelOffset, labelPos) );
|
||||
}
|
||||
|
||||
std::string ViewProviderDatumCoordinateSystem::getElement(const SoDetail* detail) const
|
||||
{
|
||||
if (detail && detail->getTypeId() == SoLineDetail::getClassTypeId()) {
|
||||
const SoLineDetail* line_detail = static_cast<const SoLineDetail*>(detail);
|
||||
switch(line_detail->getLineIndex()) {
|
||||
case 0:
|
||||
return "X";
|
||||
case 1:
|
||||
return "Y";
|
||||
case 2:
|
||||
return "Z";
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
SoDetail* ViewProviderDatumCoordinateSystem::getDetail(const char* subelement) const
|
||||
{
|
||||
if (strcmp(subelement,"X")==0) {
|
||||
SoLineDetail* detail = new SoLineDetail();
|
||||
detail->setLineIndex(0);
|
||||
return detail;
|
||||
} else if (strcmp(subelement,"Y")==0) {
|
||||
SoLineDetail* detail = new SoLineDetail();
|
||||
detail->setLineIndex(1);
|
||||
return detail;
|
||||
} else if (strcmp(subelement,"Z")==0) {
|
||||
SoLineDetail* detail = new SoLineDetail();
|
||||
detail->setLineIndex(2);
|
||||
return detail;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
class SoFont;
|
||||
class SoTranslation;
|
||||
|
||||
namespace Gui {
|
||||
class SoAutoZoomTranslation;
|
||||
}
|
||||
|
||||
namespace PartDesignGui {
|
||||
|
||||
class PartDesignGuiExport ViewProviderDatumCoordinateSystem : public PartDesignGui::ViewProviderDatum
|
||||
@@ -37,20 +41,34 @@ class PartDesignGuiExport ViewProviderDatumCoordinateSystem : public PartDesignG
|
||||
PROPERTY_HEADER(PartDesignGui::ViewProviderDatumCoordinateSystem);
|
||||
|
||||
public:
|
||||
App::PropertyFloatConstraint Zoom;
|
||||
App::PropertyIntegerConstraint FontSize;
|
||||
App::PropertyBool ShowLabel;
|
||||
|
||||
/// Constructor
|
||||
ViewProviderDatumCoordinateSystem();
|
||||
virtual ~ViewProviderDatumCoordinateSystem();
|
||||
|
||||
virtual void attach ( App::DocumentObject *obj );
|
||||
virtual void updateData(const App::Property*);
|
||||
virtual void onChanged(const App::Property*);
|
||||
|
||||
virtual void setExtents (Base::BoundBox3d bbox);
|
||||
|
||||
virtual SoDetail* getDetail(const char* subelement) const;
|
||||
virtual std::string getElement(const SoDetail* detail) const;
|
||||
|
||||
private:
|
||||
void setupLabels();
|
||||
|
||||
private:
|
||||
SoCoordinate3 *coord;
|
||||
SoTranslation *axisLabelXTrans;
|
||||
SoTranslation *axisLabelXToYTrans;
|
||||
SoTranslation *axisLabelYToZTrans;
|
||||
SoFont* font;
|
||||
SoSwitch *labelSwitch;
|
||||
Gui::SoAutoZoomTranslation *autoZoom;
|
||||
};
|
||||
|
||||
} // namespace PartDesignGui
|
||||
|
||||
Reference in New Issue
Block a user