DPG improvements

eliminate orientation matrix
remove appl logic from dialog
add 3D/Front buttons
This commit is contained in:
WandererFan 2016-11-28 19:16:14 -05:00 committed by wmayer
parent 707681534a
commit 429eb0f727
12 changed files with 821 additions and 301 deletions

View File

@ -24,7 +24,7 @@
#include "PreCompiled.h"
#include "Tools.h"
#include "Vector3D.h"
#include "Matrix.h"
using namespace Base;
template <class _Precision>
@ -96,7 +96,7 @@ Vector3<_Precision> Vector3<_Precision>::operator - (const Vector3<_Precision>&
cVctRes.z = z - rcVct.z;
return cVctRes;
}
template <class _Precision>
Vector3<_Precision> Vector3<_Precision>::operator - (void) const
{
@ -131,7 +131,7 @@ Vector3<_Precision>& Vector3<_Precision>::operator *= (_Precision fScale)
}
template <class _Precision>
Vector3<_Precision>& Vector3<_Precision>::operator /= (_Precision fDiv)
Vector3<_Precision>& Vector3<_Precision>::operator /= (_Precision fDiv)
{
x /= fDiv;
y /= fDiv;
@ -192,9 +192,47 @@ Vector3<_Precision> Vector3<_Precision>::Cross(const Vector3<_Precision>& rcVct)
return cVctRes;
}
template <class _Precision>
Matrix4D Vector3<_Precision>::Outer(const Vector3<_Precision>& rcVct) const
{
Matrix4D mat;
mat[0][0] = x * rcVct.x;
mat[0][1] = x * rcVct.y;
mat[0][2] = x * rcVct.z;
mat[1][0] = y * rcVct.x;
mat[1][1] = y * rcVct.y;
mat[1][2] = y * rcVct.z;
mat[2][0] = z * rcVct.x;
mat[2][1] = z * rcVct.y;
mat[2][2] = z * rcVct.z;
return mat;
}
template <class _Precision>
Matrix4D Vector3<_Precision>::Hat(void) const
{
Matrix4D mat;
mat[0][0] = 0.0;
mat[0][1] = -z;
mat[0][2] = y;
mat[1][0] = z;
mat[1][1] = 0.0;
mat[1][2] = -x;
mat[2][0] = -y;
mat[2][1] = x;
mat[2][2] = 0.0;
return mat;
}
template <class _Precision>
bool Vector3<_Precision>::operator != (const Vector3<_Precision>& rcVct) const
{
{
return !((*this) == rcVct);
}
@ -213,7 +251,7 @@ bool Vector3<_Precision>::IsEqual(const Vector3<_Precision> &rclPnt, _Precision
}
template <class _Precision>
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 +269,7 @@ void Vector3<_Precision>::ProjectToPlane (const Vector3 &rclBase,
}
template <class _Precision>
_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 +282,7 @@ _Precision Vector3<_Precision>::Length (void) const
}
template <class _Precision>
_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 +439,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)

View File

@ -73,6 +73,10 @@ struct float_traits<double> {
static inline float_type maximum() { return DBL_MAX; }
};
class Matrix4D;
//#include <Base/Matrix.h>
/** The Vector Base class. */
template <class _Precision>
class Vector3
@ -126,6 +130,11 @@ public:
Vector3 operator % (const Vector3<_Precision>& rcVct) const;
/// Cross product
Vector3 Cross (const Vector3<_Precision>& rcVct) const;
/// Outer product
Matrix4D Outer(const Vector3<_Precision>& rcVct) const;
/// Hat operator (skew symmetric)
Matrix4D Hat(void) const;
/// Comparing for inequality
bool operator != (const Vector3<_Precision>& rcVct) const;
/// Comparing for equality
@ -159,8 +168,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 +192,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 +295,3 @@ inline _Vec1 convertTo(const _Vec2& v)
} // namespace Base
#endif // BASE_VECTOR3D_H

View File

@ -26,6 +26,7 @@
#ifndef _PreComp_
# include <sstream>
#include <QRectF>
#include <cmath>
#endif
#include <App/Document.h>
@ -35,6 +36,7 @@
#include <Base/Console.h>
#include <Base/Exception.h>
#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<DrawProjGroupItem*>(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<TechDraw::DrawProjGroupItem *>( 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<DrawProjGroupItem *>(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<DrawProjGroupItem*>(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<DrawProjGroupItem*>(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<std::string,Base::Vector3d> 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<std::string,Base::Vector3d> 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<std::string,Base::Vector3d> DrawProjGroup::makeUnspunMap()
{
return makeUnspunMap(m_viewDir["Front"],
m_viewDir["Right"],
m_viewDir["Top"]);
}
//remake this everytime Anchor.Direction changes
std::map<std::string,Base::Vector3d> DrawProjGroup::makeUnspunMap(Base::Vector3d f, Base::Vector3d r, Base::Vector3d t)
{
std::map<std::string,Base::Vector3d> 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<std::string, Base::Vector3d>::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<DrawProjGroupItem*>(docObj);
ProjItemType t = static_cast<ProjItemType>(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<DrawProjGroupItem*>(docObj);
ProjItemType type = static_cast<ProjItemType>(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<TechDraw::DrawProjGroupItem*>( docObj );
makeInitialMap(view);
Base::Console().Log("LOG: - DPG::restore - making map from Anchor\n");
}
//dumpMap();
DrawViewCollection::onDocumentRestored();
}

View File

@ -23,12 +23,14 @@
#ifndef _TECHDRAW_FEATUREVIEWGROUP_H_
#define _TECHDRAW_FEATUREVIEWGROUP_H_
#include <string>
# include <QRectF>
#include <App/DocumentObject.h>
#include <App/PropertyStandard.h>
#include <Base/BoundBox.h>
#include <Base/Matrix.h>
#include <Base/Vector3D.h>
#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):
* <pre>
* [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
* </pre>
*/
bool hasAnchor(void);
void setAnchorDirection(Base::Vector3d dir);
Base::Vector3d getAnchorDirection(void);
void makeInitialMap(TechDraw::DrawProjGroupItem* anchor);
std::map<std::string,Base::Vector3d> makeUnspunMap(Base::Vector3d f, Base::Vector3d r, Base::Vector3d t);
std::map<std::string,Base::Vector3d> makeUnspunMap(void);
void dumpMap();
void updateSecondaryDirs();
void rotateRight(void);
void rotateLeft(void);
void rotateUp(void);
void rotateDown(void);
void spinCW(void);
void spinCCW(void);
static Base::Vector3d nameToStdDirection(std::string name);
protected:
void onChanged(const App::Property* prop);
@ -174,6 +165,8 @@ protected:
/// Returns pointer to our page, or NULL if it couldn't be located
TechDraw::DrawPage * getPage(void) const;
void updateChildren(double scale);
std::map<std::string,Base::Vector3d> m_viewDir;
};

View File

@ -34,6 +34,7 @@
#include <Mod/TechDraw/App/DrawProjGroupItemPy.h> // generated from DrawProjGroupItemPy.xml
using namespace TechDraw;
const char* DrawProjGroupItem::TypeEnums[] = {"Front",

View File

@ -30,6 +30,18 @@
namespace TechDraw
{
enum ProjItemType{ Front,
Left,
Right,
Rear,
Top,
Bottom,
FrontTopLeft,
FrontTopRight,
FrontBottomLeft,
FrontBottomRight };
class DrawProjGroup;
class TechDrawExport DrawProjGroupItem : public TechDraw::DrawViewPart

View File

@ -71,6 +71,7 @@ PyObject* DrawProjGroupPy::getItemByLabel(PyObject* args)
return new DrawProjGroupItemPy(newProj);
}
//TODO: this is no longer required?
PyObject* DrawProjGroupPy::setViewOrientation(PyObject* args)
{
const char* projType;
@ -78,15 +79,15 @@ PyObject* DrawProjGroupPy::setViewOrientation(PyObject* args)
if (!PyArg_ParseTuple(args, "Os", &pcObj,&projType))
throw Py::Exception();
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(pcObj)->getDocumentObjectPtr();
if (obj->getTypeId().isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) {
TechDraw::DrawProjGroupItem* view = static_cast<TechDraw::DrawProjGroupItem*>(obj);
TechDraw::DrawProjGroup* projGroup = getDrawProjGroupPtr();
projGroup->setViewOrientation( view, projType );
// App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(pcObj)->getDocumentObjectPtr();
// if (obj->getTypeId().isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) {
// TechDraw::DrawProjGroupItem* view = static_cast<TechDraw::DrawProjGroupItem*>(obj);
// TechDraw::DrawProjGroup* projGroup = getDrawProjGroupPtr();
// projGroup->setViewOrientation( view, projType );
} else {
Base::Console().Message("'%s' is not a DrawProjGroup Item, it will be ignored.\n", obj->Label.getValue());
}
// } else {
// Base::Console().Message("'%s' is not a DrawProjGroup Item, it will be ignored.\n", obj->Label.getValue());
// }
return Py_None;
}

View File

@ -143,6 +143,7 @@ DrawViewPart::~DrawViewPart()
App::DocumentObjectExecReturn *DrawViewPart::execute(void)
{
//Base::Console().Message("TRACE - DVP::execute() - %s\n",getNameInDocument());
App::DocumentObject *link = Source.getValue();
if (!link) {
return new App::DocumentObjectExecReturn("FVP - No Source object linked");

View File

@ -481,16 +481,17 @@ void CmdTechDrawProjGroup::activated(int iMsg)
std::string multiViewName = getUniqueObjectName("cView");
std::string SourceName = (*shapes.begin())->getNameInDocument();
doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawProjGroup','%s')",multiViewName.c_str());
doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),multiViewName.c_str());
doCommand(Doc,"App.activeDocument().%s.Source = App.activeDocument().%s",multiViewName.c_str(),SourceName.c_str());
App::DocumentObject *docObj = getDocument()->getObject(multiViewName.c_str());
auto multiView( static_cast<TechDraw::DrawProjGroup *>(docObj) );
// set the anchor
std::string anchor = "Front";
doCommand(Doc,"App.activeDocument().%s.addProjection('%s')",multiViewName.c_str(),anchor.c_str());
// std::string anchor = "Front";
// doCommand(Doc,"App.activeDocument().%s.addProjection('%s')",multiViewName.c_str(),anchor.c_str());
// add the multiView to the page
doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),multiViewName.c_str());
// doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),multiViewName.c_str());
// create the rest of the desired views
Gui::Control().showDialog(new TaskDlgProjGroup(multiView,true));

View File

@ -34,10 +34,15 @@
#include <Gui/Command.h>
#include <Gui/Control.h>
#include <Gui/Document.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Inventor/SbVec3f.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/TechDraw/App/DrawPage.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include <Mod/TechDraw/App/DrawView.h>
#include <Mod/TechDraw/App/DrawViewPart.h>
@ -51,6 +56,7 @@
#include <Mod/TechDraw/Gui/ui_TaskProjGroup.h>
using namespace Gui;
using namespace TechDraw;
using namespace TechDrawGui;
//TODO: Look into this, seems we might be able to delete it now? IR
@ -89,6 +95,11 @@ TaskProjGroup::TaskProjGroup(TechDraw::DrawProjGroup* featView, bool mode) :
connect(ui->butLeftRotate, SIGNAL(clicked()), this, SLOT(rotateButtonClicked(void)));
connect(ui->butCCWRotate, SIGNAL(clicked()), this, SLOT(rotateButtonClicked(void)));
//3D button
connect(ui->but3D, SIGNAL(clicked()), this, SLOT(on3DClicked(void)));
//Reset button
connect(ui->butReset, SIGNAL(clicked()), this, SLOT(onResetClicked(void)));
// Slot for Scale Type
connect(ui->cmbScaleType, SIGNAL(currentIndexChanged(int)), this, SLOT(scaleTypeChanged(int)));
connect(ui->sbScaleNum, SIGNAL(valueChanged(int)), this, SLOT(scaleManuallyChanged(int)));
@ -103,7 +114,7 @@ TaskProjGroup::TaskProjGroup(TechDraw::DrawProjGroup* featView, bool mode) :
ViewProviderPage* dvp = dynamic_cast<ViewProviderPage*>(vp);
m_mdi = dvp->getMDIViewPage();
setPrimaryDirection();
setUiPrimary();
}
TaskProjGroup::~TaskProjGroup()
@ -144,32 +155,50 @@ void TaskProjGroup::rotateButtonClicked(void)
if ( multiView && ui ) {
const QObject *clicked = sender();
// Any translation/scale/etc applied here will be ignored, as
// DrawProjGroup::setFrontViewOrientation() only
// uses it to set Direction and XAxisDirection.
Base::Matrix4D m = multiView->viewOrientationMatrix.getValue();
// TODO: Construct these directly
Base::Matrix4D t;
//TODO: Consider changing the vectors around depending on whether we're in First or Third angle mode - might be more intuitive? IR
if ( clicked == ui->butTopRotate ) {
t.rotX(M_PI / 2);
if ( clicked == ui->butTopRotate ) { //change Front View Dir by 90
multiView->rotateUp();
} else if ( clicked == ui->butDownRotate) {
t.rotX(M_PI / -2);
multiView->rotateDown();
} else if ( clicked == ui->butRightRotate) {
t.rotZ(M_PI / -2);
multiView->rotateRight();
} else if ( clicked == ui->butLeftRotate) {
t.rotZ(M_PI / 2);
} else if ( clicked == ui->butCWRotate ) {
t.rotY(M_PI / -2);
multiView->rotateLeft();
} else if ( clicked == ui->butCWRotate ) { //doesn't change Anchor view dir. changes projType of secondaries, not dir
multiView->spinCW();
} else if ( clicked == ui->butCCWRotate) {
t.rotY(M_PI / 2);
multiView->spinCCW();
}
m *= t;
setUiPrimary();
Gui::Command::updateActive();
}
}
multiView->setFrontViewOrientation(m);
setPrimaryDirection();
void TaskProjGroup::on3DClicked(void)
{
Base::Vector3d dir3D = get3DViewDir();
TechDraw::DrawProjGroupItem* front = multiView->getProjItem("Front");
if (front) {
front->Direction.setValue(dir3D);
front->recomputeFeature();
setUiPrimary();
multiView->makeInitialMap(front);
multiView->updateSecondaryDirs();
Gui::Command::updateActive();
}
}
void TaskProjGroup::onResetClicked(void)
{
Base::Vector3d dir = multiView->nameToStdDirection("Front");
TechDraw::DrawProjGroupItem* front = multiView->getProjItem("Front");
if (front) {
front->Direction.setValue(dir);
front->recomputeFeature();
setUiPrimary();
multiView->makeInitialMap(front);
multiView->updateSecondaryDirs();
multiView->dumpMap();
Gui::Command::updateActive();
}
}
@ -378,16 +407,37 @@ void TaskProjGroup::setupViewCheckboxes(bool addConnections)
}
}
void TaskProjGroup::setPrimaryDirection()
void TaskProjGroup::setUiPrimary()
{
App::DocumentObject* docObj = multiView->getProjObj("Front");
TechDraw::DrawViewPart* dvp = dynamic_cast<TechDraw::DrawViewPart*>(docObj);
if (dvp != nullptr) {
Base::Vector3d frontDir = dvp->Direction.getValue();
ui->lePrimary->setText(formatVector(frontDir));
}
Base::Vector3d frontDir = multiView->getAnchorDirection();
ui->lePrimary->setText(formatVector(frontDir));
}
Base::Vector3d TaskProjGroup::get3DViewDir()
{
Base::Vector3d viewDir(0.0,-1.0,0.0); //default to front
std::list<MDIView*> mdis = Gui::Application::Instance->activeDocument()->getMDIViews();
Gui::View3DInventor *view;
Gui::View3DInventorViewer *viewer;
for (auto& m: mdis) { //find the 3D viewer
view = dynamic_cast<Gui::View3DInventor*>(m);
if (view) {
viewer = view->getViewer();
break;
}
}
if (!viewer) {
Base::Console().Log("LOG - TaskProjGroup could not find a 3D viewer\n");
return viewDir;
}
SbVec3f dvec = viewer->getViewDirection();
viewDir = Base::Vector3d(dvec[0], dvec[1], dvec[2]);
viewDir = viewDir * -1; //Inventor coords are opposite projection direction coords
return viewDir;
}
QString TaskProjGroup::formatVector(Base::Vector3d v)
{
QString data = QString::fromLatin1("[%1 %2 %3]")

View File

@ -75,6 +75,9 @@ protected Q_SLOTS:
/// Requests appropriate rotation of our DrawProjGroup
void rotateButtonClicked(void);
void on3DClicked(void);
void onResetClicked(void);
void projectionTypeChanged(int index);
void scaleTypeChanged(int index);
void scaleManuallyChanged(int i);
@ -88,8 +91,8 @@ protected:
* between checkboxes and viewToggled()
*/
void setupViewCheckboxes(bool addConnections = false);
void setPrimaryDirection(void);
Base::Vector3d get3DViewDir(void);
void setUiPrimary(void);
QString formatVector(Base::Vector3d v);
private:

View File

@ -57,6 +57,9 @@
</item>
<item>
<widget class="QComboBox" name="projection">
<property name="toolTip">
<string>First or Third Angle</string>
</property>
<property name="editable">
<bool>false</bool>
</property>
@ -90,6 +93,9 @@
</item>
<item>
<widget class="QComboBox" name="cmbScaleType">
<property name="toolTip">
<string>Scale Page/Auto/Custom</string>
</property>
<item>
<property name="text">
<string>Page</string>
@ -133,6 +139,9 @@
</item>
<item>
<widget class="QSpinBox" name="sbScaleNum">
<property name="toolTip">
<string>Scale Numerator</string>
</property>
<property name="minimum">
<number>1</number>
</property>
@ -150,6 +159,9 @@
</item>
<item>
<widget class="QSpinBox" name="sbScaleDen">
<property name="toolTip">
<string>Scale Denominator</string>
</property>
<property name="minimum">
<number>1</number>
</property>
@ -205,7 +217,7 @@
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<pointsize>11</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
@ -214,6 +226,9 @@
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Primary View Direction</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
@ -292,9 +307,12 @@
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="pushButton_8">
<widget class="QPushButton" name="but3D">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="toolTip">
<string>Set Primary Direction to match 3D</string>
</property>
<property name="text">
<string>Match 3D</string>
@ -322,6 +340,16 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="butReset">
<property name="toolTip">
<string>Set Primary Direction to 3D Front</string>
</property>
<property name="text">
<string>3D Front</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
@ -345,8 +373,236 @@
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="5" column="2">
<widget class="QCheckBox" name="chkView8">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Bottom</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="2">
<widget class="QCheckBox" name="chkView4">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Primary</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QCheckBox" name="chkView5">
<property name="toolTip">
<string>Right</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="5">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="chkView3">
<property name="toolTip">
<string>Left</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="chkView7">
<property name="toolTip">
<string>LeftFrontBottom</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="chkView1">
<property name="toolTip">
<string>Top</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QCheckBox" name="chkView9">
<property name="toolTip">
<string>RightFrontBottom</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QCheckBox" name="chkView2">
<property name="toolTip">
<string>RightFrontTop</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QCheckBox" name="chkView6">
<property name="toolTip">
<string>Rear</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="chkView0">
<property name="toolTip">
<string>LeftFrontTop</string>
</property>
<property name="styleSheet">
<string notr="true">QCheckBox::indicator {
width: 24px;
height: 24px;
}
</string>
</property>
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="butCWRotate">
<property name="toolTip">
@ -377,22 +633,8 @@
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="5" column="2">
<widget class="QCheckBox" name="chkView8">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="horizontalSpacer">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -404,88 +646,6 @@
</property>
</spacer>
</item>
<item row="3" column="2">
<widget class="QCheckBox" name="chkView4">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QCheckBox" name="chkView5">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="5">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="chkView3">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="chkView7">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="chkView1">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QCheckBox" name="chkView9">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QCheckBox" name="chkView2">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QCheckBox" name="chkView6">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="chkView0">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>