diff --git a/src/App/Extension.cpp b/src/App/Extension.cpp
index 962ef781c..94aff5ce4 100644
--- a/src/App/Extension.cpp
+++ b/src/App/Extension.cpp
@@ -33,6 +33,7 @@
#include "Base/Exception.h"
#include
#include
+#include
/* We do not use a standard property macro for type initiation. The reason is that we have the first
* PropertyData in the extension chain, there is no parent property data.
@@ -96,7 +97,12 @@ void Extension::initExtension(ExtensionContainer* obj) {
PyObject* Extension::getExtensionPyObject(void) {
- return nullptr;
+ if (ExtensionPythonObject.is(Py::_None())){
+ // ref counter is set to 1
+ auto grp = new ExtensionPy(this);
+ ExtensionPythonObject = Py::Object(grp,true);
+ }
+ return Py::new_reference_to(ExtensionPythonObject);
}
const char* Extension::name() {
diff --git a/src/App/GroupExtension.h b/src/App/GroupExtension.h
index 7e24846a5..01fe0fa79 100644
--- a/src/App/GroupExtension.h
+++ b/src/App/GroupExtension.h
@@ -117,7 +117,7 @@ public:
EXTENSION_PROXY_ONEARG(allowObject, pyobj);
if(result.isNone())
- ExtensionT::allowObject(obj);
+ return ExtensionT::allowObject(obj);
if(result.isBoolean())
return result.isTrue();
diff --git a/src/Base/Matrix.cpp b/src/Base/Matrix.cpp
index bf9b5810d..f27267dbd 100644
--- a/src/Base/Matrix.cpp
+++ b/src/Base/Matrix.cpp
@@ -871,3 +871,79 @@ std::string Matrix4D::analyse(void) const
}
return text;
}
+
+Matrix4D& Matrix4D::Outer(const Vector3f& rV1, const Vector3f& rV2)
+{
+ setToUnity();
+
+ dMtrx4D[0][0] = rV1.x * rV2.x;
+ dMtrx4D[0][1] = rV1.x * rV2.y;
+ dMtrx4D[0][2] = rV1.x * rV2.z;
+
+ dMtrx4D[1][0] = rV1.y * rV2.x;
+ dMtrx4D[1][1] = rV1.y * rV2.y;
+ dMtrx4D[1][2] = rV1.y * rV2.z;
+
+ dMtrx4D[2][0] = rV1.z * rV2.x;
+ dMtrx4D[2][1] = rV1.z * rV2.y;
+ dMtrx4D[2][2] = rV1.z * rV2.z;
+
+ return *this;
+}
+
+Matrix4D& Matrix4D::Outer(const Vector3d& rV1, const Vector3d& rV2)
+{
+ setToUnity();
+
+ dMtrx4D[0][0] = rV1.x * rV2.x;
+ dMtrx4D[0][1] = rV1.x * rV2.y;
+ dMtrx4D[0][2] = rV1.x * rV2.z;
+
+ dMtrx4D[1][0] = rV1.y * rV2.x;
+ dMtrx4D[1][1] = rV1.y * rV2.y;
+ dMtrx4D[1][2] = rV1.y * rV2.z;
+
+ dMtrx4D[2][0] = rV1.z * rV2.x;
+ dMtrx4D[2][1] = rV1.z * rV2.y;
+ dMtrx4D[2][2] = rV1.z * rV2.z;
+
+ return *this;
+}
+
+Matrix4D& Matrix4D::Hat(const Vector3f& rV)
+{
+ setToUnity();
+
+ dMtrx4D[0][0] = 0.0;
+ dMtrx4D[0][1] = -rV.z;
+ dMtrx4D[0][2] = rV.y;
+
+ dMtrx4D[1][0] = rV.z;
+ dMtrx4D[1][1] = 0.0;
+ dMtrx4D[1][2] = -rV.x;
+
+ dMtrx4D[2][0] = -rV.y;
+ dMtrx4D[2][1] = rV.x;
+ dMtrx4D[2][2] = 0.0;
+
+ return *this;
+}
+
+Matrix4D& Matrix4D::Hat(const Vector3d& rV)
+{
+ setToUnity();
+
+ dMtrx4D[0][0] = 0.0;
+ dMtrx4D[0][1] = -rV.z;
+ dMtrx4D[0][2] = rV.y;
+
+ dMtrx4D[1][0] = rV.z;
+ dMtrx4D[1][1] = 0.0;
+ dMtrx4D[1][2] = -rV.x;
+
+ dMtrx4D[2][0] = -rV.y;
+ dMtrx4D[2][1] = rV.x;
+ dMtrx4D[2][2] = 0.0;
+
+ return *this;
+}
diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h
index a7986fb6b..dc27d349a 100644
--- a/src/Base/Matrix.h
+++ b/src/Base/Matrix.h
@@ -95,6 +95,12 @@ public:
double determinant() const;
/// Analyse the transformation
std::string analyse(void) const;
+ /// Outer product (Dyadic product)
+ Matrix4D& Outer(const Vector3f& rV1, const Vector3f& rV2);
+ Matrix4D& Outer(const Vector3d& rV1, const Vector3d& rV2);
+ /// Hat operator (skew symmetric)
+ Matrix4D& Hat(const Vector3f& rV);
+ Matrix4D& Hat(const Vector3d& rV);
//@}
void getMatrix (double dMtrx[16]) const;
diff --git a/src/Base/Vector3D.cpp b/src/Base/Vector3D.cpp
index 782ee4a44..0d0729013 100644
--- a/src/Base/Vector3D.cpp
+++ b/src/Base/Vector3D.cpp
@@ -96,7 +96,7 @@ Vector3<_Precision> Vector3<_Precision>::operator - (const Vector3<_Precision>&
cVctRes.z = z - rcVct.z;
return cVctRes;
}
-
+
template
Vector3<_Precision> Vector3<_Precision>::operator - (void) const
{
@@ -131,7 +131,7 @@ Vector3<_Precision>& Vector3<_Precision>::operator *= (_Precision fScale)
}
template
-Vector3<_Precision>& Vector3<_Precision>::operator /= (_Precision fDiv)
+Vector3<_Precision>& Vector3<_Precision>::operator /= (_Precision fDiv)
{
x /= fDiv;
y /= fDiv;
@@ -194,7 +194,7 @@ Vector3<_Precision> Vector3<_Precision>::Cross(const Vector3<_Precision>& rcVct)
template
bool Vector3<_Precision>::operator != (const Vector3<_Precision>& rcVct) const
-{
+{
return !((*this) == rcVct);
}
@@ -213,7 +213,7 @@ bool Vector3<_Precision>::IsEqual(const Vector3<_Precision> &rclPnt, _Precision
}
template
-Vector3<_Precision>& Vector3<_Precision>::ProjectToPlane (const Vector3<_Precision> &rclBase,
+Vector3<_Precision>& Vector3<_Precision>::ProjectToPlane (const Vector3<_Precision> &rclBase,
const Vector3<_Precision> &rclNorm)
{
Vector3<_Precision> clTemp(rclNorm);
@@ -231,7 +231,7 @@ void Vector3<_Precision>::ProjectToPlane (const Vector3 &rclBase,
}
template
-_Precision Vector3<_Precision>::DistanceToPlane (const Vector3<_Precision> &rclBase,
+_Precision Vector3<_Precision>::DistanceToPlane (const Vector3<_Precision> &rclBase,
const Vector3<_Precision> &rclNorm) const
{
return ((*this - rclBase) * rclNorm) / rclNorm.Length();
@@ -244,7 +244,7 @@ _Precision Vector3<_Precision>::Length (void) const
}
template
-_Precision Vector3<_Precision>::DistanceToLine (const Vector3<_Precision> &rclBase,
+_Precision Vector3<_Precision>::DistanceToLine (const Vector3<_Precision> &rclBase,
const Vector3<_Precision> &rclDirect) const
{
return (_Precision) fabs((rclDirect % Vector3(*this - rclBase)).Length() / rclDirect.Length());
@@ -401,7 +401,7 @@ _Precision Vector3<_Precision>::GetAngle (const Vector3 &rcVect) const
_Precision divid, fNum;
divid = Length() * ((Vector3<_Precision>&)rcVect).Length();
-
+
if ((divid < -1e-10f) || (divid > 1e-10f)) {
fNum = (*this * rcVect) / divid;
if (fNum < -1)
diff --git a/src/Base/Vector3D.h b/src/Base/Vector3D.h
index da39a80af..f6816cc5d 100644
--- a/src/Base/Vector3D.h
+++ b/src/Base/Vector3D.h
@@ -126,6 +126,7 @@ public:
Vector3 operator % (const Vector3<_Precision>& rcVct) const;
/// Cross product
Vector3 Cross (const Vector3<_Precision>& rcVct) const;
+
/// Comparing for inequality
bool operator != (const Vector3<_Precision>& rcVct) const;
/// Comparing for equality
@@ -159,8 +160,8 @@ public:
Vector3 & Normalize (void);
/// Get angle between both vectors. The returned value lies in the interval [0,pi].
_Precision GetAngle (const Vector3 &rcVect) const;
- /** Transforms this point to the coordinate system defined by origin \a rclBase,
- * vector \a vector rclDirX and vector \a vector rclDirY.
+ /** Transforms this point to the coordinate system defined by origin \a rclBase,
+ * vector \a vector rclDirX and vector \a vector rclDirY.
* \note \a rclDirX must be perpendicular to \a rclDirY, i.e. \a rclDirX * \a rclDirY = 0..
*/
void TransformToCoordinateSystem (const Vector3 &rclBase, const Vector3 &rclDirX, const Vector3 &rclDirY);
@@ -183,7 +184,7 @@ public:
/// Projects this point onto the line given by the base \a rclPoint and the direction \a rclLine.
/**
* Projects a point \a rclPoint onto the line defined by the origin and the direction \a rclLine.
- * The result is a vector from \a rclPoint to the point on the line. The length of this vector
+ * The result is a vector from \a rclPoint to the point on the line. The length of this vector
* is the distance from \a rclPoint to the line.
* Note: The resulting vector does not depend on the current vector.
*/
@@ -286,4 +287,3 @@ inline _Vec1 convertTo(const _Vec2& v)
} // namespace Base
#endif // BASE_VECTOR3D_H
-
diff --git a/src/Gui/ViewProvider.cpp b/src/Gui/ViewProvider.cpp
index 3a1224f50..5d1cbe2b6 100644
--- a/src/Gui/ViewProvider.cpp
+++ b/src/Gui/ViewProvider.cpp
@@ -580,9 +580,12 @@ void ViewProvider::dragObject(App::DocumentObject* obj) {
bool ViewProvider::canDropObject(App::DocumentObject* obj) const {
auto vector = getExtensionsDerivedFromType();
- for(Gui::ViewProviderExtension* ext : vector)
+ Base::Console().Message("Check extensions for drop\n");
+ for(Gui::ViewProviderExtension* ext : vector){
+ Base::Console().Message("Check extensions %s\n", ext->name());
if(ext->extensionCanDropObject(obj))
return true;
+ }
return false;
}
diff --git a/src/Gui/ViewProviderExtension.h b/src/Gui/ViewProviderExtension.h
index 636a5d50a..bde1f2323 100644
--- a/src/Gui/ViewProviderExtension.h
+++ b/src/Gui/ViewProviderExtension.h
@@ -97,13 +97,14 @@ public:
ViewProviderExtensionPythonT() {
ExtensionT::m_isPythonExtension = true;
+ ExtensionT::initExtension(ViewProviderExtensionPythonT::getExtensionClassTypeId());
- EXTENSION_ADD_PROPERTY(Proxy,(Py::Object()));
+ EXTENSION_ADD_PROPERTY(ExtensionProxy,(Py::Object()));
}
virtual ~ViewProviderExtensionPythonT() {
}
- App::PropertyPythonObject Proxy;
+ App::PropertyPythonObject ExtensionProxy;
};
typedef ViewProviderExtensionPythonT ViewProviderExtensionPython;
diff --git a/src/Gui/ViewProviderGroupExtension.cpp b/src/Gui/ViewProviderGroupExtension.cpp
index db1ead3de..03050117b 100644
--- a/src/Gui/ViewProviderGroupExtension.cpp
+++ b/src/Gui/ViewProviderGroupExtension.cpp
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include
using namespace Gui;
@@ -76,6 +77,8 @@ bool ViewProviderGroupExtension::extensionCanDropObjects() const {
bool ViewProviderGroupExtension::extensionCanDropObject(App::DocumentObject* obj) const {
+ Base::Console().Message("Check ViewProviderGroupExtension");
+
auto* group = getExtendedViewProvider()->getObject()->getExtensionByType();
//we cannot drop thing of this group into it again
diff --git a/src/Gui/ViewProviderPy.xml b/src/Gui/ViewProviderPy.xml
index 9087834a4..732a5d43f 100644
--- a/src/Gui/ViewProviderPy.xml
+++ b/src/Gui/ViewProviderPy.xml
@@ -1,13 +1,13 @@
diff --git a/src/Mod/Part/App/ArcOfConicPyImp.cpp b/src/Mod/Part/App/ArcOfConicPyImp.cpp
index ef90ab370..e6806f5ec 100644
--- a/src/Mod/Part/App/ArcOfConicPyImp.cpp
+++ b/src/Mod/Part/App/ArcOfConicPyImp.cpp
@@ -51,7 +51,7 @@ PyObject *ArcOfConicPy::PyMake(struct _typeobject *, PyObject *, PyObject *) //
}
// constructor method
-int ArcOfConicPy::PyInit(PyObject* args, PyObject* /*kwds*/)
+int ArcOfConicPy::PyInit(PyObject* /*args*/, PyObject* /*kwds*/)
{
return -1;
}
diff --git a/src/Mod/Part/App/Geom2d/Curve2dPyImp.cpp b/src/Mod/Part/App/Geom2d/Curve2dPyImp.cpp
index be49457e7..40cc226d5 100644
--- a/src/Mod/Part/App/Geom2d/Curve2dPyImp.cpp
+++ b/src/Mod/Part/App/Geom2d/Curve2dPyImp.cpp
@@ -87,7 +87,7 @@ int Curve2dPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
return 0;
}
-PyObject* Curve2dPy::reverse(PyObject *args)
+PyObject* Curve2dPy::reverse(PyObject * /*args*/)
{
try {
Handle_Geom2d_Curve curve = Handle_Geom2d_Curve::DownCast(getGeom2dCurvePtr()->handle());
diff --git a/src/Mod/Path/PathScripts/PathPost.py b/src/Mod/Path/PathScripts/PathPost.py
index 1827b3d04..1be6689bc 100644
--- a/src/Mod/Path/PathScripts/PathPost.py
+++ b/src/Mod/Path/PathScripts/PathPost.py
@@ -162,6 +162,28 @@ class CommandPathPost:
return True
return False
+ def exportObjectsWith(self, objs, job, needFilename = True):
+ # check if the user has a project and has set the default post and
+ # output filename
+ postArgs = PathPreferences.defaultPostProcessorArgs()
+ if hasattr(job, "PostProcessorArgs") and job.PostProcessorArgs:
+ postArgs = job.PostProcessorArgs
+ elif hasattr(job, "PostProcessor") and job.PostProcessor:
+ postArgs = ''
+
+ postname = self.resolvePostProcessor(job)
+ filename = '-'
+ if postname and needFilename:
+ filename = self.resolveFileName(job)
+
+ if postname and filename:
+ print("post: %s(%s, %s)" % (postname, filename, postArgs))
+ processor = PostProcessor.load(postname)
+ gcode = processor.export(objs, filename, postArgs)
+ return (False, gcode)
+ else:
+ return (True, '')
+
def Activated(self):
FreeCAD.ActiveDocument.openTransaction(
translate("Path_Post", "Post Process the Selected path(s)"))
@@ -187,7 +209,7 @@ class CommandPathPost:
else:
job = jobs.pop()
print("Job for selected objects = %s" % job.Name)
- (fail, rc) = exportObjectsWith(selected, job)
+ (fail, rc) = self.exportObjectsWith(selected, job)
if fail:
FreeCAD.ActiveDocument.abortTransaction()
@@ -195,27 +217,7 @@ class CommandPathPost:
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
- def exportObjectsWith(self, objs, job, needFilename = True):
- # check if the user has a project and has set the default post and
- # output filename
- postArgs = PathPreferences.defaultPostProcessorArgs()
- if hasattr(job, "PostProcessorArgs") and job.PostProcessorArgs:
- postArgs = job.PostProcessorArgs
- elif hasattr(job, "PostProcessor") and job.PostProcessor:
- postArgs = ''
- postname = self.resolvePostProcessor(job)
- filename = '-'
- if postname and needFilename:
- filename = self.resolveFileName(job)
-
- if postname and filename:
- print("post: %s(%s, %s)" % (postname, filename, postArgs))
- processor = PostProcessor.load(postname)
- gcode = processor.export(objs, filename, postArgs)
- return (False, gcode)
- else:
- return (True, '')
if FreeCAD.GuiUp:
# register the FreeCAD command
diff --git a/src/Mod/TechDraw/App/DrawProjGroup.cpp b/src/Mod/TechDraw/App/DrawProjGroup.cpp
index 9c9304b61..ebb729ad2 100644
--- a/src/Mod/TechDraw/App/DrawProjGroup.cpp
+++ b/src/Mod/TechDraw/App/DrawProjGroup.cpp
@@ -26,6 +26,7 @@
#ifndef _PreComp_
# include
#include
+#include
#endif
#include
@@ -35,6 +36,7 @@
#include
#include
+
#include "DrawUtil.h"
#include "DrawPage.h"
#include "DrawProjGroupItem.h"
@@ -65,13 +67,91 @@ DrawProjGroup::DrawProjGroup(void)
ADD_PROPERTY_TYPE(spacingX, (15), agroup, App::Prop_None, "Horizontal spacing between views");
ADD_PROPERTY_TYPE(spacingY, (15), agroup, App::Prop_None, "Vertical spacing between views");
- ADD_PROPERTY(viewOrientationMatrix, (Base::Matrix4D()));
}
DrawProjGroup::~DrawProjGroup()
{
}
+void DrawProjGroup::onChanged(const App::Property* prop)
+{
+ //TODO: For some reason, when the projection type is changed, the isometric views show change appropriately, but the orthographic ones dont... Or vice-versa. why would you change from 1st to 3rd in mid drawing?
+ //if group hasn't been added to page yet, can't scale or distribute projItems
+ TechDraw::DrawPage *page = getPage();
+ if (!isRestoring() && page) {
+ if ( prop == &Views ) {
+ recompute();
+ } else if (prop == &Scale) {
+ updateChildren(Scale.getValue());
+ //resetPositions();
+ distributeProjections();
+ } else if (prop == &Source) {
+ App::DocumentObject* sourceObj = Source.getValue();
+ if (sourceObj != nullptr) {
+ if (!hasAnchor()) {
+ addProjection("Front");
+ }
+ } else {
+ //Source has been changed to null! Why? What to do?
+ }
+ } else if (prop == &ScaleType) {
+ recompute();
+ } else if (prop == &AutoDistribute &&
+ AutoDistribute.getValue()) {
+ resetPositions();
+ recompute();
+ }
+ }
+ TechDraw::DrawViewCollection::onChanged(prop);
+}
+
+App::DocumentObjectExecReturn *DrawProjGroup::execute(void)
+{
+ //if group hasn't been added to page yet, can't scale or distribute projItems
+ TechDraw::DrawPage *page = getPage();
+ if (!page) {
+ return DrawViewCollection::execute();
+ }
+
+ App::DocumentObject* docObj = Source.getValue();
+ if (docObj == nullptr) {
+ return DrawViewCollection::execute();
+ }
+
+ docObj = Anchor.getValue(); //must have an anchor, so create one as soon as we have a Page and Source
+ if (docObj == nullptr) {
+ docObj = addProjection("Front");
+ }
+
+ double newScale = Scale.getValue();
+ if (ScaleType.isValue("Automatic")) {
+ //Recalculate scale if Group is too big or too small!
+ if (!checkFit(page)) {
+ newScale = calculateAutomaticScale();
+ if(std::abs(Scale.getValue() - newScale) > FLT_EPSILON) {
+ resetPositions();
+ Scale.setValue(newScale);
+ }
+ }
+ } else if (ScaleType.isValue("Page")) {
+ newScale = page->Scale.getValue();
+ if(std::abs(Scale.getValue() - newScale) > FLT_EPSILON) {
+ resetPositions();
+ Scale.setValue(newScale);
+ }
+ } else if (ScaleType.isValue("Custom")) {
+ //don't have to do anything special
+ }
+
+ // recalculate positions for children
+ if (Views.getSize()) {
+ updateChildren(newScale);
+ distributeProjections();
+ }
+
+ return DrawViewCollection::execute();
+}
+
short DrawProjGroup::mustExecute() const
{
short result = 0;
@@ -169,7 +249,6 @@ QRectF DrawProjGroup::getRect() const //this is current rect, not potent
arrangeViewPointers(viewPtrs);
double width, height;
minimumBbViews(viewPtrs, width, height); // w,h of just the views at 1:1 scale
- //need to add spacingX,spacingY
double xSpace = spacingX.getValue() * 3.0 * std::max(1.0,Scale.getValue());
double ySpace = spacingY.getValue() * 2.0 * std::max(1.0,Scale.getValue());
double rectW = Scale.getValue() * width + xSpace; //scale the 1:1 w,h and add whitespace
@@ -200,28 +279,6 @@ void DrawProjGroup::minimumBbViews(DrawProjGroupItem *viewPtrs[10],
height = row0h + row1h + row2h;
}
-void DrawProjGroup::onChanged(const App::Property* prop)
-{
- //TODO: For some reason, when the projection type is changed, the isometric views show change appropriately, but the orthographic ones dont... Or vice-versa.
- //if group hasn't been added to page yet, can't scale or distribute projItems
- TechDraw::DrawPage *page = getPage();
- if (!isRestoring() && page) {
- if ( prop == &Views ) {
- recompute();
- } else if (prop == &Scale) {
- updateChildren(Scale.getValue());
- //resetPositions();
- distributeProjections();
- } else if (prop == &ScaleType) {
- recompute();
- } else if (prop == &AutoDistribute &&
- AutoDistribute.getValue()) {
- resetPositions();
- recompute();
- }
- }
- TechDraw::DrawViewCollection::onChanged(prop);
-}
void DrawProjGroup::moveToCentre(void)
{
@@ -247,6 +304,14 @@ App::DocumentObject * DrawProjGroup::getProjObj(const char *viewProjType) const
return 0;
}
+DrawProjGroupItem* DrawProjGroup::getProjItem(const char *viewProjType) const
+{
+ App::DocumentObject* docObj = getProjObj(viewProjType);
+ DrawProjGroupItem* result = static_cast(docObj);
+ return result;
+}
+
+
bool DrawProjGroup::checkViewProjType(const char *in)
{
if ( strcmp(in, "Front") == 0 ||
@@ -288,9 +353,6 @@ App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType)
std::string FeatName = getDocument()->getUniqueObjectName("ProjItem");
auto docObj( getDocument()->addObject( "TechDraw::DrawProjGroupItem", //add to Document
FeatName.c_str() ) );
- if( strcmp(viewProjType,"Front") == 0 ) {
- Anchor.setValue(docObj);
- }
view = static_cast( docObj );
view->Source.setValue( Source.getValue() );
if (ScaleType.isValue("Automatic")) {
@@ -301,7 +363,17 @@ App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType)
view->Scale.setValue( Scale.getValue() );
view->Type.setValue( viewProjType );
view->Label.setValue( viewProjType );
- setViewOrientation( view, viewProjType );
+ if( strcmp(viewProjType,"Front") == 0 ) {
+
+ Anchor.setValue(docObj);
+ view->Direction.setValue(nameToStdDirection("Front")); //just (Base::Vector3d(0.0,-1.0,0.0))
+ view->recomputeFeature();
+ makeInitialMap(view);
+ //dumpMap();
+ } else {
+ //dumpMap();
+ view->Direction.setValue(m_viewDir[viewProjType]);
+ }
addView(view); //from DrawViewCollection - add to ProjGroup Views
moveToCentre();
@@ -351,44 +423,6 @@ int DrawProjGroup::purgeProjections()
return Views.getValues().size();
}
-void DrawProjGroup::setViewOrientation(DrawProjGroupItem *v, const char *projType) const
-{
- Base::Vector3d dir;
-
- // Traditional orthographic
- if(strcmp(projType, "Front") == 0) {
- dir.Set(0, -1, 0);
- } else if(strcmp(projType, "Rear") == 0) {
- dir.Set(0, 1, 0);
- } else if(strcmp(projType, "Right") == 0) {
- dir.Set(1, 0, 0);
- } else if(strcmp(projType, "Left") == 0) {
- dir.Set(-1, 0, 0);
- } else if(strcmp(projType, "Top") == 0) {
- dir.Set(0, 0, 1);
- } else if(strcmp(projType, "Bottom") == 0) {
- dir.Set(0, 0, -1);
-
- // Isometric
- } else if(strcmp(projType, "FrontTopLeft") == 0) {
- dir.Set(-1,-1,1);
- dir.Normalize();
- } else if(strcmp(projType, "FrontTopRight") == 0) {
- dir.Set(1, -1, 1);
- dir.Normalize();
- } else if(strcmp(projType, "FrontBottomRight") == 0) {
- dir.Set(1, -1, -1);
- dir.Normalize();
- } else if(strcmp(projType, "FrontBottomLeft") == 0) {
- dir.Set(-1, -1, -1);
- dir.Normalize();
- } else {
- throw Base::Exception("Unknown view type in DrawProjGroup::setViewOrientation()");
- }
- dir = viewOrientationMatrix.getValue() * dir; //multiply std dir by transform matrix
- v->Direction.setValue(dir);
-}
-
void DrawProjGroup::arrangeViewPointers(DrawProjGroupItem *viewPtrs[10]) const
{
for (int i=0; i<10; ++i) {
@@ -570,58 +604,7 @@ void DrawProjGroup::resetPositions(void)
}
}
-//TODO: Turn this into a command so it can be issued from python
-//????: this sets the orientation for all views, not just Front???
-void DrawProjGroup::setFrontViewOrientation(const Base::Matrix4D &newMat)
-{
- viewOrientationMatrix.setValue(newMat);
- for( auto it : Views.getValues() ) {
- auto view( dynamic_cast(it) );
- if( view ) {
- setViewOrientation(view, view->Type.getValueAsString());
- // TODO: Seems we should ensure that modifying the view triggers this automatically? IR
- view->touch();
- }
- }
-}
-
-App::DocumentObjectExecReturn *DrawProjGroup::execute(void)
-{
- //if group hasn't been added to page yet, can't scale or distribute projItems
- TechDraw::DrawPage *page = getPage();
- if (!page) {
- return DrawViewCollection::execute();
- }
-
- double newScale = Scale.getValue();
- if (ScaleType.isValue("Automatic")) {
- //Recalculate scale if Group is too big or too small!
- if (!checkFit(page)) {
- newScale = calculateAutomaticScale();
- if(std::abs(Scale.getValue() - newScale) > FLT_EPSILON) {
- resetPositions();
- Scale.setValue(newScale);
- }
- }
- } else if (ScaleType.isValue("Page")) {
- newScale = page->Scale.getValue();
- if(std::abs(Scale.getValue() - newScale) > FLT_EPSILON) {
- resetPositions();
- Scale.setValue(newScale);
- }
- } else if (ScaleType.isValue("Custom")) {
- //don't have to do anything special
- }
-
- // recalculate positions for children
- if (Views.getSize()) {
- updateChildren(newScale);
- //resetPositions();
- distributeProjections();
- }
- return DrawViewCollection::execute();
-}
void DrawProjGroup::updateChildren(double scale)
{
@@ -686,8 +669,277 @@ App::Enumeration DrawProjGroup::usedProjectionType(void)
return ret;
}
+bool DrawProjGroup::hasAnchor(void)
+{
+ bool result = false;
+ App::DocumentObject* docObj = Anchor.getValue();
+ if (docObj != nullptr) {
+ result = true;
+ }
+ return result;
+}
+
+
+
+void DrawProjGroup::setAnchorDirection(const Base::Vector3d dir)
+{
+ App::DocumentObject* docObj = Anchor.getValue();
+ DrawProjGroupItem* item = static_cast(docObj);
+ item->Direction.setValue(dir);
+}
+
+Base::Vector3d DrawProjGroup::getAnchorDirection(void)
+{
+ Base::Vector3d result;
+ App::DocumentObject* docObj = Anchor.getValue();
+ if (docObj != nullptr) {
+ DrawProjGroupItem* item = static_cast(docObj);
+ result = item->Direction.getValue();
+ } else {
+ Base::Console().Log("ERROR - DPG::getAnchorDir - no Anchor!!\n");
+ }
+ return result;
+}
+
+//static
+Base::Vector3d DrawProjGroup::nameToStdDirection(std::string name)
+{
+ Base::Vector3d result;
+ //name to standard view direction
+ std::map stdViews = {
+ { "Front", Base::Vector3d(0, -1, 0) },
+ { "Rear", Base::Vector3d(0, 1, 0) },
+ { "Right", Base::Vector3d(1, 0, 0) },
+ { "Left", Base::Vector3d(-1, 0, 0) },
+ { "Top", Base::Vector3d(0, 0, 1) },
+ { "Bottom", Base::Vector3d(0, 0, -1) },
+ { "FrontTopLeft", Base::Vector3d(-1,-1,1) },
+ { "FrontTopRight", Base::Vector3d(1, -1, 1) },
+ { "FrontBottomRight", Base::Vector3d(1, -1, -1) },
+ { "FrontBottomLeft", Base::Vector3d(-1, -1, -1) } };
+ auto it = stdViews.find(name);
+ if (it != stdViews.end()) {
+ result = (*it).second;
+ }
+ return result;
+}
+
+
+//*************************************
+//* view direction manipulation routines
+//*************************************
+
+//make map from anchor u,v,w
+//std::map DrawProjGroup::makeInitialMap(TechDraw::DrawProjGroupItem* anchor)
+void DrawProjGroup::makeInitialMap(TechDraw::DrawProjGroupItem* anchor)
+{
+ m_viewDir = makeUnspunMap(anchor->Direction.getValue(),
+ anchor->getUDir(),
+ anchor->getVDir() * -1); //the infamous flipped Y
+}
+
+//! remake map from FRT
+std::map DrawProjGroup::makeUnspunMap()
+{
+ return makeUnspunMap(m_viewDir["Front"],
+ m_viewDir["Right"],
+ m_viewDir["Top"]);
+}
+
+//remake this everytime Anchor.Direction changes
+std::map DrawProjGroup::makeUnspunMap(Base::Vector3d f, Base::Vector3d r, Base::Vector3d t)
+{
+ std::map viewDir;
+ viewDir["Front"] = f;
+ viewDir["Right"] = r;
+ viewDir["Top"] = t;
+ viewDir["Rear"] = viewDir["Front"] * -1.0;
+ viewDir["Left"] = viewDir["Right"] * -1.0;
+ viewDir["Bottom"] = viewDir["Top"] * -1.0;
+ viewDir["FrontTopRight"] = viewDir["Right"] + viewDir["Front"] + viewDir["Top"];
+ viewDir["FrontTopLeft"] = viewDir["Left"] + viewDir["Front"] + viewDir["Top"];
+ viewDir["FrontBottomRight"] = viewDir["Right"] + viewDir["Front"] + viewDir["Bottom"];
+ viewDir["FrontBottomLeft"] = viewDir["Left"] + viewDir["Front"] + viewDir["Bottom"];
+ return viewDir;
+}
+
+void DrawProjGroup::dumpMap()
+{
+ Base::Console().Message("TRACE - DPG::dumpMap - entries: %d\n",m_viewDir.size());
+ std::map::const_iterator it;
+ for (it = m_viewDir.begin(); it != m_viewDir.end(); it++)
+ {
+ Base::Console().Message("%s - %s\n",(it->first).c_str(), DrawUtil::formatVector(it->second).c_str());
+ }
+}
+
+void DrawProjGroup::updateSecondaryDirs()
+{
+ for (auto& docObj: Views.getValues()) {
+ Base::Vector3d newDir;
+ DrawProjGroupItem* v = static_cast(docObj);
+ ProjItemType t = static_cast(v->Type.getValue());
+ switch (t) {
+ case Front : {
+ newDir = m_viewDir["Front"];
+ break;
+ }
+ case Rear : {
+ newDir = m_viewDir["Rear"];
+ break;
+ }
+ case Left : {
+ newDir = m_viewDir["Left"];
+ break;
+ }
+ case Right : {
+ newDir = m_viewDir["Right"];
+ break;
+ }
+ case Top : {
+ newDir = m_viewDir["Top"];
+ break;
+ }
+ case Bottom : {
+ newDir = m_viewDir["Bottom"];
+ break;
+ }
+ case FrontTopLeft : {
+ newDir = m_viewDir["FrontTopLeft"];
+ break;
+ }
+ case FrontTopRight : {
+ newDir = m_viewDir["FrontTopRight"];
+ break;
+ }
+ case FrontBottomLeft : {
+ newDir = m_viewDir["FrontBottomLeft"];
+ break;
+ }
+ case FrontBottomRight : {
+ newDir = m_viewDir["FrontBottomRight"];
+ break;
+ }
+ default: {
+ //TARFU invalid secondary type
+ Base::Console().Message("ERROR - DPG::updateSecondaryDirs - invalid projection type\n");
+ newDir = v->Direction.getValue();
+ }
+ }
+ v->Direction.setValue(newDir);
+ }
+}
+
+
+void DrawProjGroup::rotateRight()
+{
+//Front -> Right -> Rear -> Left -> Front
+ Base::Vector3d f,r,t;
+ f = m_viewDir["Left"];
+ r = m_viewDir["Front"];
+ t = m_viewDir["Top"];
+ m_viewDir = makeUnspunMap(f,r,t);
+ updateSecondaryDirs();
+}
+
+void DrawProjGroup::rotateLeft()
+{
+//Front -> Left -> Rear -> Right -> Front
+ Base::Vector3d f,r,t;
+ f = m_viewDir["Right"];
+ r = m_viewDir["Rear"];
+ t = m_viewDir["Top"];
+ m_viewDir = makeUnspunMap(f,r,t);
+ updateSecondaryDirs();
+}
+
+void DrawProjGroup::rotateUp()
+{
+//Front -> Top -> Rear -> Bottom -> Front
+ Base::Vector3d f,r,t;
+ f = m_viewDir["Bottom"];
+ r = m_viewDir["Right"];
+ t = m_viewDir["Front"];
+ m_viewDir = makeUnspunMap(f,r,t);
+ updateSecondaryDirs();
+}
+
+void DrawProjGroup::rotateDown()
+{
+//Front -> Bottom -> Rear -> Top -> Front
+ Base::Vector3d f,r,t;
+ f = m_viewDir["Top"];
+ r = m_viewDir["Right"];
+ t = m_viewDir["Rear"];
+ m_viewDir = makeUnspunMap(f,r,t);
+ updateSecondaryDirs();
+}
+
+void DrawProjGroup::spinCW()
+{
+//Top -> Right -> Bottom -> Left -> Top
+ Base::Vector3d f,r,t;
+ f = m_viewDir["Front"];
+ t = m_viewDir["Left"];
+ r = m_viewDir["Top"];
+ m_viewDir = makeUnspunMap(f,r,t);
+ updateSecondaryDirs();
+}
+
+void DrawProjGroup::spinCCW()
+{
+//Top -> Left -> Bottom -> Right -> Top
+ Base::Vector3d f,r,t;
+ f = m_viewDir["Front"];
+ t = m_viewDir["Right"];
+ r = m_viewDir["Bottom"];
+ m_viewDir = makeUnspunMap(f,r,t);
+ updateSecondaryDirs();
+}
+
+//*************************************
+
+//! rebuild view direction map from existing DPGI's if possible or from Anchor
void DrawProjGroup::onDocumentRestored()
{
+ Base::Vector3d f,r,t;
+ bool ffound = false;
+ bool rfound = false;
+ bool tfound = false;
+
+ for (auto& docObj: Views.getValues()) {
+ DrawProjGroupItem* v = static_cast(docObj);
+ ProjItemType type = static_cast(v->Type.getValue());
+ switch (type) {
+ case Front : {
+ f = v->Direction.getValue();
+ ffound = true;
+ break;
+ }
+ case Right : {
+ r = v->Direction.getValue();
+ rfound = true;
+ break;
+ }
+ case Top : {
+ t = v->Direction.getValue();
+ tfound = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ if (ffound && rfound && tfound) {
+ m_viewDir = makeUnspunMap(f,r,t);
+ } else {
+ App::DocumentObject* docObj = Anchor.getValue();
+ TechDraw::DrawProjGroupItem* view = static_cast( docObj );
+ makeInitialMap(view);
+ Base::Console().Log("LOG: - DPG::restore - making map from Anchor\n");
+ }
+ //dumpMap();
DrawViewCollection::onDocumentRestored();
}
diff --git a/src/Mod/TechDraw/App/DrawProjGroup.h b/src/Mod/TechDraw/App/DrawProjGroup.h
index b84164fa2..2cd2b7299 100644
--- a/src/Mod/TechDraw/App/DrawProjGroup.h
+++ b/src/Mod/TechDraw/App/DrawProjGroup.h
@@ -23,12 +23,14 @@
#ifndef _TECHDRAW_FEATUREVIEWGROUP_H_
#define _TECHDRAW_FEATUREVIEWGROUP_H_
+#include
# include
#include
#include
#include
#include
+#include
#include "DrawViewCollection.h"
@@ -58,9 +60,6 @@ public:
/// Default vertical spacing between adjacent views on Drawing, in mm
App::PropertyFloat spacingY;
- /// Transforms Direction and XAxisDirection vectors in child views
- App::PropertyMatrix viewOrientationMatrix;
-
App::PropertyLink Anchor; /// Anchor Element to align views to
Base::BoundBox3d getBoundingBox() const;
@@ -71,6 +70,7 @@ public:
bool hasProjection(const char *viewProjType) const;
App::DocumentObject * getProjObj(const char *viewProjType) const;
+ DrawProjGroupItem* getProjItem(const char *viewProjType) const;
//! Adds a projection to the group
/*!
@@ -88,11 +88,6 @@ public:
/// Automatically position child views
bool distributeProjections(void);
void resetPositions(void);
- /// Changes child views' coordinate space
- /*!
- * Used to set the Direction and XAxisDirection in child views
- */
- void setFrontViewOrientation(const Base::Matrix4D &newMat);
short mustExecute() const;
/** @name methods overide Feature */
@@ -115,29 +110,25 @@ public:
/// Allowed projection types - either Document, First Angle or Third Angle
static const char* ProjectionTypeEnums[];
- /// Sets Direction in v
- /*!
- * Applies viewOrientationMatrix to appropriate unit vectors depending on projType
- */
- void setViewOrientation(DrawProjGroupItem *v, const char *projType) const;
- /// Populates an array of DrawProjGroupItem*s arranged for drawing
- /*!
- * Setup array of pointers to the views that we're displaying,
- * assuming front is in centre (index 4):
- *
- * [0] [1] [2]
- * [3] [4] [5] [6]
- * [7] [8] [9]
- *
- * Third Angle: FTL T FTRight
- * L F Right Rear
- * FBL B FBRight
- *
- * First Angle: FBRight B FBL
- * Right F L Rear
- * FTRight T FTL
- *