diff --git a/src/Mod/TechDraw/App/CMakeLists.txt b/src/Mod/TechDraw/App/CMakeLists.txt index cbdd9ecb1e..5b279ccfe2 100644 --- a/src/Mod/TechDraw/App/CMakeLists.txt +++ b/src/Mod/TechDraw/App/CMakeLists.txt @@ -96,8 +96,6 @@ SET(TechDraw_SRCS AppTechDrawPy.cpp DrawUtil.cpp DrawUtil.h - Cube.cpp - Cube.h HatchLine.cpp HatchLine.h PreCompiled.cpp diff --git a/src/Mod/TechDraw/App/Cube.cpp b/src/Mod/TechDraw/App/Cube.cpp deleted file mode 100644 index 28a92ff366..0000000000 --- a/src/Mod/TechDraw/App/Cube.cpp +++ /dev/null @@ -1,565 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2016 WandererFan * - * * - * 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 -#endif - -#include - -#include "DrawUtil.h" -#include "Cube.h" - -using namespace TechDraw; - -//default starting dirs & rots -const std::map Cube::m_viewDefault = { - { "Front", Base::Vector3d(0, -1, 0) }, //front - { "Rear", Base::Vector3d(0, 1, 0) }, //rear - { "Right", Base::Vector3d(1, 0, 0) }, //right - { "Left", Base::Vector3d(-1, 0, 0) }, //left - { "Top", Base::Vector3d(0, 0, 1) }, //top - { "Bottom", Base::Vector3d(0, 0, -1) }, //bottom - }; - -const std::map Cube::m_rotDefault = { - { "Front", Base::Vector3d(1, 0, 0) }, //front RightDir - { "Rear", Base::Vector3d(-1, 0, 0) }, //rear LeftDir - { "Right", Base::Vector3d(0, -1, 0) }, //right FrontDir - { "Left", Base::Vector3d(0, 1, 0) }, //left RearDir - { "Top", Base::Vector3d(1, 0, 0) }, //top RightDir - { "Bottom", Base::Vector3d(1, 0, 0) }, //bottom RightDir - }; - -const Base::Vector3d _Y(0,1,0); - - -Cube::Cube(void) -{ -} - -Cube::~Cube(void) -{ -} - -void Cube::initialize() -{ - m_mapCubeDir = m_viewDefault; - m_mapCubeRot = m_rotDefault; -} - -// left,right,front,back,top,bottom -void Cube::initialize(Base::Vector3d r, Base::Vector3d rr, Base::Vector3d l, Base::Vector3d lr, - Base::Vector3d f, Base::Vector3d fr, Base::Vector3d k, Base::Vector3d kr, //k for bacK (rear) - Base::Vector3d t, Base::Vector3d tr, Base::Vector3d b, Base::Vector3d br) -{ - m_mapCubeDir.clear(); - m_mapCubeDir.insert(std::map::value_type("Bottom", b)); - m_mapCubeDir.insert(std::map::value_type("Front" , f)); - m_mapCubeDir.insert(std::map::value_type("Left" , l)); - m_mapCubeDir.insert(std::map::value_type("Rear" , k)); - m_mapCubeDir.insert(std::map::value_type("Right" , r)); - m_mapCubeDir.insert(std::map::value_type("Top" , t)); - - m_mapCubeRot.clear(); - m_mapCubeRot.insert(std::map::value_type("Bottom", br)); - m_mapCubeRot.insert(std::map::value_type("Front" , fr)); - m_mapCubeRot.insert(std::map::value_type("Left" , lr)); - m_mapCubeRot.insert(std::map::value_type("Rear" , kr)); - m_mapCubeRot.insert(std::map::value_type("Right" , rr)); - m_mapCubeRot.insert(std::map::value_type("Top" , tr)); -} - -// rotate/spin the subject inside the glass cube -// effectively, rotate/spin the cube in reverse of the apparent subject movement - -//TODO: there is a problem with calculation of view rotation vector when the axis of rotation is -// +/-Y. There is hack code here to handle it, but there should be a more elegant solution - -// subject CW about Right -void Cube::rotateUp(double angle) -{ - //Front -> Top -> Rear -> Bottom -> Front - Base::Vector3d axis = getRight(); - std::map newDirs; - for (auto& d: m_mapCubeDir) { - Base::Vector3d v = rodrigues(d.second,angle,axis); - newDirs.insert(std::map::value_type(d.first, v)); - } - - std::map newRots; - for (auto& r: m_mapCubeRot) { - Base::Vector3d v = rodrigues(r.second,-angle,axis); - newRots.insert(std::map::value_type(r.first, v)); - } - - double flipper = 1.0; - if (DrawUtil::checkParallel(axis,_Y)) { - flipper = -flipper; - newRots["Right"] = newRots["Right"] * flipper; - newRots["Left"] = newRots["Left"] * flipper; - } - - m_mapCubeDir = newDirs; - m_mapCubeRot = newRots; -} - -// CCW about Right -void Cube::rotateDown(double angle) -{ - //Front -> Bottom -> Rear -> Top -> Front - Base::Vector3d axis = getRight(); - std::map newDirs; - for (auto& d: m_mapCubeDir) { - Base::Vector3d v = rodrigues(d.second,-angle,axis); - newDirs.insert(std::map::value_type(d.first, v)); - } - - std::map newRots; - for (auto& r: m_mapCubeRot) { - Base::Vector3d v = rodrigues(r.second,angle,axis); - newRots.insert(std::map::value_type(r.first, v)); - } - - double flipper = 1.0; - if (DrawUtil::checkParallel(axis,_Y)) { - flipper = -flipper; - newRots["Right"] = newRots["Right"] * flipper; - newRots["Left"] = newRots["Left"] * flipper; - } - - m_mapCubeDir = newDirs; - m_mapCubeRot = newRots; -} - -// CCW about Top -void Cube::rotateRight(double angle) -{ - //Front -> Right -> Rear -> Left -> Front - Base::Vector3d axis = getTop(); - std::map newDirs; - for (auto& d: m_mapCubeDir) { - Base::Vector3d v = rodrigues(d.second,-angle,axis); - newDirs.insert(std::map::value_type(d.first, v)); - } - - std::map newRots; - for (auto& r: m_mapCubeRot) { - Base::Vector3d v = rodrigues(r.second,angle,axis); - newRots.insert(std::map::value_type(r.first, v)); - } - - double flipper = 1.0; - if (DrawUtil::checkParallel(axis,_Y)) { - flipper = -flipper; - newRots["Top"] = newRots["Top"] * flipper; - newRots["Bottom"] = newRots["Bottom"] * flipper; - newRots["Left"] = newDirs["Front"]; - newRots["Right"] = newRots["Left"] * -1.0; - } - newRots["Front"] = newRots["Top"]; - newRots["Rear"] = newRots["Front"] * -1.0; - - m_mapCubeDir = newDirs; - m_mapCubeRot = newRots; -} - -// CW about Top -void Cube::rotateLeft(double angle) -{ - //Front -> Left -> Rear -> Right -> Front - Base::Vector3d axis = getTop(); - std::map newDirs; - for (auto& d: m_mapCubeDir) { - Base::Vector3d v = rodrigues(d.second,angle,axis); - newDirs.insert(std::map::value_type(d.first, v)); - } - - std::map newRots; - for (auto& r: m_mapCubeRot) { - Base::Vector3d v = rodrigues(r.second,-angle,axis); - newRots.insert(std::map::value_type(r.first, v)); - } - - double flipper = 1.0; - if (DrawUtil::checkParallel(axis,_Y)) { - flipper = -flipper; - newRots["Top"] = newRots["Top"] * flipper; - newRots["Bottom"] = newRots["Bottom"] * flipper; - newRots["Left"] = newDirs["Front"]; - newRots["Right"] = newRots["Left"] * -1.0; - } - newRots["Front"] = newRots["Top"]; - newRots["Rear"] = newRots["Front"] * -1.0; - - m_mapCubeDir = newDirs; - m_mapCubeRot = newRots; -} - -// CCW about Front -void Cube::spinCCW(double angle) -{ - Base::Vector3d axis = getFront(); - std::map newDirs; - for (auto& d: m_mapCubeDir) { - Base::Vector3d v = rodrigues(d.second,-angle,axis); - newDirs.insert(std::map::value_type(d.first, v)); - } - std::map newRots; - for (auto& r: m_mapCubeRot) { - Base::Vector3d v = rodrigues(r.second,angle,axis); - newRots.insert(std::map::value_type(r.first, v)); - } - - double flipper = 1.0; - if (DrawUtil::checkParallel(axis,_Y)) { - flipper = -flipper; - } - newRots["Front"] = newRots["Front"] * flipper; - newRots["Rear"] = newRots["Rear"] * flipper; - newRots["Top"] = newRots["Front"]; - newRots["Bottom"] = newRots["Front"]; - - m_mapCubeDir = newDirs; - m_mapCubeRot = newRots; -} - -// CW about Front -void Cube::spinCW(double angle) -{ - //Right -> Bottom -> Left -> Top -> Right - Base::Vector3d axis = getFront(); - std::map newDirs; - for (auto& d: m_mapCubeDir) { - Base::Vector3d v = rodrigues(d.second,angle,axis); - newDirs.insert(std::map::value_type(d.first, v)); - } - - std::map newRots; - for (auto& r: m_mapCubeRot) { - Base::Vector3d v = rodrigues(r.second,-angle,axis); - newRots.insert(std::map::value_type(r.first, v)); - } - double flipper = 1.0; - if (DrawUtil::checkParallel(axis,_Y)) { - flipper = -flipper; - newRots["Front"] = newRots["Front"] * flipper; - newRots["Rear"] = newRots["Rear"] * flipper; - } - newRots["Top"] = newRots["Front"]; - newRots["Bottom"] = newRots["Front"]; - - m_mapCubeDir = newDirs; - m_mapCubeRot = newRots; -} - -//dumps the current ortho state of cube -void Cube::dump(char * title) -{ -//Bottom/Front/Left/Rear/Right/Top - Base::Console().Message("Cube: %s\n", title); - Base::Console().Message("B: %s/%s \nF: %s/%s \nL: %s/%s\n", - DrawUtil::formatVector(getBottom()).c_str(),DrawUtil::formatVector(getBottomRot()).c_str(), - DrawUtil::formatVector(getFront()).c_str(),DrawUtil::formatVector(getFrontRot()).c_str(), - DrawUtil::formatVector(getLeft()).c_str(),DrawUtil::formatVector(getLeftRot()).c_str()); - Base::Console().Message("K: %s/%s \nR: %s/%s \nT: %s/%s\n", - DrawUtil::formatVector(getRear()).c_str(),DrawUtil::formatVector(getRearRot()).c_str(), - DrawUtil::formatVector(getRight()).c_str(),DrawUtil::formatVector(getRightRot()).c_str(), - DrawUtil::formatVector(getTop()).c_str(),DrawUtil::formatVector(getTopRot()).c_str()); -} - -//dumps the current "board" -ISO's -void Cube::dumpISO(char * title) -{ -//FBL/FBR/FTL/FTR - Base::Console().Message("Cube ISO: %s\n", title); - Base::Console().Message("FBL: %s/%s \nFBR: %s/%s \nFTL: %s/%s\nFTR: %s/%s\n", - DrawUtil::formatVector(getFBL()).c_str(),DrawUtil::formatVector(getFBLRot()).c_str(), - DrawUtil::formatVector(getFBR()).c_str(),DrawUtil::formatVector(getFBRRot()).c_str(), - DrawUtil::formatVector(getFTL()).c_str(),DrawUtil::formatVector(getFTLRot()).c_str(), - DrawUtil::formatVector(getFTR()).c_str(),DrawUtil::formatVector(getFTRRot()).c_str()); -} - -Base::Vector3d Cube::getViewDir(std::string name) -{ - Base::Vector3d result; - auto x = m_mapCubeDir.find(name); - if (x != m_mapCubeDir.end()) { - result = m_mapCubeDir.at(name); - } else { - if (name == "FrontTopRight") { - result = getFTR(); - } else if (name == "FrontBottomRight") { - result = getFBR(); - } else if (name == "FrontTopLeft") { - result = getFTL(); - } else if (name == "FrontBottomLeft") { - result = getFBL(); - } else { - result = Base::Vector3d(0,-1,0); - Base::Console().Log("Cube: invalid direction name - %s\n",name.c_str()); - } - } - return result; -} - -Base::Vector3d Cube::getRight() -{ - Base::Vector3d result; - result = m_mapCubeDir.at("Right"); - return result; -} - -Base::Vector3d Cube::getFront() -{ - Base::Vector3d result; - result = m_mapCubeDir.at("Front"); - return result; -} - -Base::Vector3d Cube::getTop() -{ - Base::Vector3d result; - result = m_mapCubeDir.at("Top"); - return result; -} - -Base::Vector3d Cube::getLeft() -{ - Base::Vector3d result; - result = m_mapCubeDir.at("Left"); - return result; -} - -Base::Vector3d Cube::getRear() -{ - Base::Vector3d result; - result = m_mapCubeDir.at("Rear"); - return result; -} - -Base::Vector3d Cube::getBottom() -{ - Base::Vector3d result; - result = m_mapCubeDir.at("Bottom"); - return result; -} - -Base::Vector3d Cube::getFBL() -{ - Base::Vector3d result; - result = getFront() + getBottom() + getLeft(); - return result; -} - -Base::Vector3d Cube::getFBR() -{ - Base::Vector3d result; - result = getFront() + getBottom() + getRight(); - return result; -} - -Base::Vector3d Cube::getFTL() -{ - Base::Vector3d result; - result = getFront() + getTop() + getLeft(); - return result; -} - -Base::Vector3d Cube::getFTR() -{ - Base::Vector3d result; - result = getFront() + getTop() + getRight(); - return result; -} - -Base::Vector3d Cube::getRotationDir(std::string name) -{ - Base::Vector3d result; - auto x = m_mapCubeRot.find(name); - if (x != m_mapCubeRot.end()) { - result = m_mapCubeRot.at(name); - } else { - if (name == "FrontTopRight") { - result = getFTRRot(); - } else if (name == "FrontBottomRight") { - result = getFBRRot(); - } else if (name == "FrontTopLeft") { - result = getFTLRot(); - } else if (name == "FrontBottomLeft") { - result = getFBLRot(); - } else { - result = Base::Vector3d(1,0,0); - Base::Console().Log("Cube: invalid rotation name - %s\n",name.c_str()); - } - } - return result; -} - -Base::Vector3d Cube::getRightRot() -{ - Base::Vector3d result; - result = m_mapCubeRot.at("Right"); - return result; -} - -Base::Vector3d Cube::getFrontRot() -{ - Base::Vector3d result; - result = m_mapCubeRot.at("Front"); - return result; -} - -Base::Vector3d Cube::getTopRot() -{ - Base::Vector3d result; - result = m_mapCubeRot.at("Top"); - return result; -} - -Base::Vector3d Cube::getLeftRot() -{ - Base::Vector3d result; - result = m_mapCubeRot.at("Left"); - return result; -} - -Base::Vector3d Cube::getRearRot() -{ - Base::Vector3d result; - result = m_mapCubeRot.at("Rear"); - return result; -} - -Base::Vector3d Cube::getBottomRot() -{ - Base::Vector3d result; - result = m_mapCubeRot.at("Bottom"); - return result; -} - -Base::Vector3d Cube::getFBLRot() -{ - Base::Vector3d result; - result = getFrontRot() + getLeftRot(); - return result; -} - -Base::Vector3d Cube::getFBRRot() -{ - Base::Vector3d result; - result = getFrontRot() + getRightRot(); - return result; -} - -Base::Vector3d Cube::getFTLRot() -{ - Base::Vector3d result; - result = getFrontRot() + getLeftRot(); - return result; -} - -Base::Vector3d Cube::getFTRRot() -{ - Base::Vector3d result; - result = getFrontRot() + getRightRot(); - return result; -} - -Base::Vector3d Cube::rodrigues(Base::Vector3d v, - double angle, - Base::Vector3d axis) -{ - Base::Vector3d result; - if (DrawUtil::checkParallel(v,axis)) { - result = v; - } else { - Base::Vector3d around = axis; - around.Normalize(); - double theta = angle * (M_PI / 180.0); - Base::Vector3d t1 = cos(theta) * v; - Base::Vector3d t2 = sin(theta) * around.Cross(v); - Base::Vector3d t3 = around.Dot(v) * (1 - cos(theta)) * around; - result = t1 + t2 + t3; - } - return result; -} - -std::vector Cube::getAllDirs(void) -{ - std::vector result; - for (auto& d: m_mapCubeDir) { - Base::Vector3d v = d.second; - result.push_back(v); - } - return result; -} - -std::vector Cube::getAllRots(void) -{ - std::vector result; - for (auto& r: m_mapCubeRot) { - Base::Vector3d v = r.second; - result.push_back(v); - } - return result; -} - -void Cube::setAllDirs(std::vector dirs) -{ - if (dirs.size() != 6) { - Base::Console().Error("Cube:setAllDirs - missing dirs: %d\n",dirs.size()); - return; //throw something? - } - - auto i = dirs.begin(); - std::map newDirs; - for (auto& d: m_mapCubeDir) { - Base::Vector3d v = (*i); - newDirs.insert(std::map::value_type(d.first, v)); - i++; - } - m_mapCubeDir = newDirs; -} - -void Cube::setAllRots(std::vector rots) -{ - if (rots.size() != 6) { - Base::Console().Error("Cube:setAllRots - missing rots: %d\n",rots.size()); - return; //throw something? - } - - auto i = rots.begin(); - std::map newRots; - for (auto& r: m_mapCubeRot) { - Base::Vector3d v = (*i); - newRots.insert(std::map::value_type(r.first, v)); - i++; - } - m_mapCubeRot = newRots; -} - - - - diff --git a/src/Mod/TechDraw/App/Cube.h b/src/Mod/TechDraw/App/Cube.h deleted file mode 100644 index 6d268f36f9..0000000000 --- a/src/Mod/TechDraw/App/Cube.h +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2016 WandererFan * - * * - * 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 _CUBE_H_ -#define _CUBE_H_ - -#include - -#include - -namespace TechDraw -{ - - -class Cube -{ -public: - Cube(); - ~Cube(); - -void initialize(); -void initialize(Base::Vector3d r, Base::Vector3d rr, Base::Vector3d l, Base::Vector3d lr, - Base::Vector3d f, Base::Vector3d fr, Base::Vector3d k, Base::Vector3d kr, //k for bacK (rear) - Base::Vector3d t, Base::Vector3d tr, Base::Vector3d b, Base::Vector3d br); - - - - void rotateUp(double angle = 90.0); - void rotateDown(double angle = 90.0); - void rotateRight(double angle = 90.0); - void rotateLeft (double angle = 90.0); - void spinCCW(double angle = 90.0); - void spinCW(double angle = 90.0); - void updateIsoDirs(); - - //viewDirection getters - Base::Vector3d getViewDir(std::string name); - Base::Vector3d getRight(); - Base::Vector3d getFront(); - Base::Vector3d getTop(); - Base::Vector3d getLeft(); - Base::Vector3d getRear(); - Base::Vector3d getBottom(); - Base::Vector3d getFBL(); - Base::Vector3d getFBR(); - Base::Vector3d getFTL(); - Base::Vector3d getFTR(); - - //rotation getters - Base::Vector3d getRotationDir(std::string name); - Base::Vector3d getRightRot(); - Base::Vector3d getFrontRot(); - Base::Vector3d getTopRot(); - Base::Vector3d getLeftRot(); - Base::Vector3d getRearRot(); - Base::Vector3d getBottomRot(); - Base::Vector3d getFBLRot(); - Base::Vector3d getFBRRot(); - Base::Vector3d getFTLRot(); - Base::Vector3d getFTRRot(); - - void dump(char * title); - void dumpISO(char * title); - - std::vector getAllDirs(void); - std::vector getAllRots(void); - void setAllDirs(std::vector dirs); - void setAllRots(std::vector rots); - -private: - //the current state of the "cube" - //the "cube" is always full - entries for every ortho position (6 total) - std::map m_mapCubeDir; - std::map m_mapCubeRot; - - static const std::map m_viewDefault; - static const std::map m_rotDefault; - -//should be in drawutil? - Base::Vector3d rodrigues(Base::Vector3d v, - double angle, - Base::Vector3d axis); - -}; - -} -#endif - - diff --git a/src/Mod/TechDraw/App/DrawProjGroup.cpp b/src/Mod/TechDraw/App/DrawProjGroup.cpp index bcdf2b4a6d..aa46056f32 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroup.cpp @@ -39,7 +39,6 @@ #include #include -#include "Cube.h" #include "DrawUtil.h" #include "DrawPage.h" #include "DrawProjGroupItem.h" @@ -77,23 +76,12 @@ DrawProjGroup::DrawProjGroup(void) ADD_PROPERTY_TYPE(AutoDistribute ,(autoDist),agroup,App::Prop_None,"Distribute Views Automatically or Manually"); 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_TYPE(CubeDirs,(Base::Vector3d()) ,agroup, App::Prop_None, "Current view directions"); - ADD_PROPERTY_TYPE(CubeRotations,(Base::Vector3d()),agroup, App::Prop_None, "Current rotations"); - m_cube = new Cube(); - m_cube->initialize(); //set default dirs & rots } DrawProjGroup::~DrawProjGroup() { - delete m_cube; } -void DrawProjGroup::resetCube(void) -{ - m_cube->initialize(); - updateSecondaryDirs(); -} void DrawProjGroup::onChanged(const App::Property* prop) { @@ -106,6 +94,7 @@ void DrawProjGroup::onChanged(const App::Property* prop) if (!sourceObjs.empty()) { if (!hasAnchor()) { // if we have a Source, but no Anchor, make an anchor +// Base::Console().Message("TRACE - DPG::onChanged - adding Front\n"); Anchor.setValue(addProjection("Front")); Anchor.purgeTouched(); //don't need to mark this } @@ -137,28 +126,10 @@ void DrawProjGroup::onChanged(const App::Property* prop) } } - if (isRestoring() && (prop == &CubeDirs)) { - m_cube->setAllDirs(CubeDirs.getValues()); //override defaults from saved value if valid - } - if (isRestoring() && (prop == &CubeRotations)) { - m_cube->setAllRots(CubeRotations.getValues()); //override defaults from saved value if valid - } - + TechDraw::DrawViewCollection::onChanged(prop); } -//! call this after changing the Cube -void DrawProjGroup::setPropsFromCube(void) -{ - CubeDirs.setValues(m_cube->getAllDirs()); - CubeRotations.setValues(m_cube->getAllRots()); -} - -void DrawProjGroup::setCubeFromProps(void) -{ - m_cube->setAllDirs(CubeDirs.getValues()); - m_cube->setAllRots(CubeRotations.getValues()); -} App::DocumentObjectExecReturn *DrawProjGroup::execute(void) { if (!keepUpdated()) { @@ -392,6 +363,8 @@ bool DrawProjGroup::hasProjection(const char *viewProjType) const App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType) { DrawProjGroupItem *view( nullptr ); + std::pair vecs; + if ( checkViewProjType(viewProjType) && !hasProjection(viewProjType) ) { std::string FeatName = getDocument()->getUniqueObjectName("ProjItem"); @@ -403,8 +376,12 @@ App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType) view->Type.setValue( viewProjType ); view->Label.setValue( viewProjType ); view->Source.setValues( Source.getValues() ); - view->Direction.setValue(m_cube->getViewDir(viewProjType)); - view->RotationVector.setValue(m_cube->getRotationDir(viewProjType)); + if (strcmp(viewProjType, "Front") != 0 ) { + vecs = getDirsFromFront(view); + view->Direction.setValue(vecs.first); + view->RotationVector.setValue(vecs.second); + } + addView(view); //from DrawViewCollection moveToCentre(); if (view != getAnchor()) { //anchor is done elsewhere @@ -462,6 +439,76 @@ int DrawProjGroup::purgeProjections() return Views.getValues().size(); } +std::pair DrawProjGroup::getDirsFromFront(DrawProjGroupItem* view) +{ + std::pair result; + std::string viewType = view->Type.getValueAsString(); + result = getDirsFromFront(viewType); + return result; +} + +std::pair DrawProjGroup::getDirsFromFront(std::string viewType) +{ + std::pair result; + + Base::Vector3d projDir, rotVec; + DrawProjGroupItem* anch = getAnchor(); + + Base::Vector3d dirAnch = anch->Direction.getValue(); + Base::Vector3d rotAnch = anch->RotationVector.getValue(); + Base::Vector3d upAnch = dirAnch.Cross(rotAnch); //this can get weird after rotations + projDir = dirAnch; //need default + rotVec = rotAnch; + Base::Vector3d realUp = DrawUtil::closestBasis(upAnch); + + Base::Vector3d org(0.0,0.0,0.0); + result = std::make_pair(dirAnch,rotAnch); + double angle = M_PI / 2.0; //90* + + if (viewType == "Right") { + projDir = DrawUtil::vecRotate(dirAnch,angle,realUp,org); + rotVec = DrawUtil::vecRotate(rotAnch,angle,upAnch,org); + } else if (viewType == "Left") { + projDir = DrawUtil::vecRotate(dirAnch,-angle,realUp,org); + rotVec = DrawUtil::vecRotate(rotAnch,-angle,upAnch,org); + } else if (viewType == "Top") { + projDir = upAnch; + rotVec = rotAnch; + } else if (viewType == "Bottom") { + projDir = upAnch * (-1.0); + rotVec = rotAnch; + } else if (viewType == "Rear") { + projDir = DrawUtil::vecRotate(dirAnch,2.0 * angle,realUp,org); + rotVec = -rotAnch; + } else if (viewType == "FrontTopLeft") { + projDir = dirAnch + //front + DrawUtil::vecRotate(dirAnch,-angle,realUp,org) + //left + upAnch; //top + rotVec = rotAnch + dirAnch; //sb current front rot + curr right rot + } else if (viewType == "FrontTopRight") { + projDir = dirAnch + //front + DrawUtil::vecRotate(dirAnch,angle,realUp,org) + //right + upAnch; //top + rotVec = rotAnch - dirAnch; + } else if (viewType == "FrontBottomLeft") { + projDir = dirAnch + //front + DrawUtil::vecRotate(dirAnch,-angle,realUp,org) + //left + upAnch * (-1.0); //bottom + rotVec = rotAnch + dirAnch; + } else if (viewType == "FrontBottomRight") { + projDir = dirAnch + //front + DrawUtil::vecRotate(dirAnch,angle,realUp,org) + //right + upAnch * (-1.0); //bottom + rotVec = rotAnch - dirAnch; + } else { + Base::Console().Error("DrawProjGroup - %s unknown projection: %s\n",getNameInDocument(),viewType.c_str()); + return result; + } + + result = std::make_pair(projDir,rotVec); + return result; +} + Base::Vector3d DrawProjGroup::getXYPosition(const char *viewTypeCStr) { Base::Vector3d result; @@ -833,74 +880,109 @@ Base::Vector3d DrawProjGroup::getAnchorDirection(void) void DrawProjGroup::updateSecondaryDirs() { + DrawProjGroupItem* anchor = getAnchor(); + Base::Vector3d anchDir = anchor->Direction.getValue(); + Base::Vector3d anchRot = anchor->RotationVector.getValue(); + + std::map > saveVals; + std::string key; + std::pair data; for (auto& docObj: Views.getValues()) { Base::Vector3d newDir; - Base::Vector3d newAxis; + Base::Vector3d newRot; + std::pair newDirs; std::string pic; DrawProjGroupItem* v = static_cast(docObj); ProjItemType t = static_cast(v->Type.getValue()); switch (t) { - case Front : { - newDir = m_cube->getFront(); - newAxis = m_cube->getFrontRot(); + case Front : + data.first = anchDir; + data.second = anchRot; + key = "Front"; + saveVals[key] = data; break; - } - case Rear : { - newDir = m_cube->getRear(); - newAxis = m_cube->getRearRot(); + case Rear : + key = "Rear"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; +// newDir = newDirs.first; +// newRot = newDirs.second; break; - } - case Left : { - newDir = m_cube->getLeft(); - newAxis = m_cube->getLeftRot(); + case Left : + key = "Left"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; +// newDir = newDirs.first; +// newRot = newDirs.second; break; - } - case Right : { - newDir = m_cube->getRight(); - newAxis = m_cube->getRightRot(); + case Right : + key = "Right"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; +// newDir = newDirs.first; +// newRot = newDirs.second; break; - } - case Top : { - newDir = m_cube->getTop(); - newAxis = m_cube->getTopRot(); + case Top : + key = "Top"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; +// newDir = newDirs.first; +// newRot = newDirs.second; break; - } - case Bottom : { - newDir = m_cube->getBottom(); - newAxis = m_cube->getBottomRot(); + case Bottom : + key = "Bottom"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; +// newDir = newDirs.first; +// newRot = newDirs.second; break; - } - case FrontTopLeft : { - newDir = m_cube->getFTL(); - newAxis = m_cube->getFTLRot(); + case FrontTopLeft : + key = "FrontTopLeft"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; +// newDir = newDirs.first; +// newRot = newDirs.second; break; - } - case FrontTopRight : { - newDir = m_cube->getFTR(); - newAxis = m_cube->getFTRRot(); + case FrontTopRight : + key = "FrontTopRight"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; +// newDir = newDirs.first; +// newRot = newDirs.second; break; - } - case FrontBottomLeft : { - newDir = m_cube->getFBL(); - newAxis = m_cube->getFBLRot(); + case FrontBottomLeft : + key = "FrontBottomLeft"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; +// newDir = newDirs.first; +// newRot = newDirs.second; break; - } - case FrontBottomRight : { - newDir = m_cube->getFBR(); - newAxis = m_cube->getFBRRot(); + case FrontBottomRight : + key = "FrontBottomRight"; + newDirs = getDirsFromFront(key); + saveVals[key] = newDirs; + newDir = newDirs.first; + newRot = newDirs.second; break; - } default: { //TARFU invalid secondary type Base::Console().Message("ERROR - DPG::updateSecondaryDirs - invalid projection type\n"); newDir = v->Direction.getValue(); - newAxis = v->RotationVector.getValue(); + newRot = v->RotationVector.getValue(); } } - v->Direction.setValue(newDir); - v->RotationVector.setValue(newAxis); +// v->Direction.setValue(newDir); +// v->RotationVector.setValue(newRot); + } + + //not sure if this is required. + for (auto& docObj: Views.getValues()) { + DrawProjGroupItem* v = static_cast(docObj); + std::string type = v->Type.getValueAsString(); + data = saveVals[type]; + v->Direction.setValue(data.first); + v->RotationVector.setValue(data.second); } - setPropsFromCube(); auto page = findParentPage(); if (page != nullptr) { @@ -908,46 +990,74 @@ void DrawProjGroup::updateSecondaryDirs() } } - void DrawProjGroup::rotateRight() { //Front -> Right -> Rear -> Left -> Front - m_cube->rotateRight(); + std::pair newDirs; + newDirs = getDirsFromFront("Left"); + DrawProjGroupItem* anchor = getAnchor(); + anchor->Direction.setValue(newDirs.first); + anchor->RotationVector.setValue(newDirs.second); updateSecondaryDirs(); } void DrawProjGroup::rotateLeft() { //Front -> Left -> Rear -> Right -> Front - m_cube->rotateLeft(); + std::pair newDirs; + newDirs = getDirsFromFront("Right"); + DrawProjGroupItem* anchor = getAnchor(); + anchor->Direction.setValue(newDirs.first); + anchor->RotationVector.setValue(newDirs.second); updateSecondaryDirs(); } void DrawProjGroup::rotateUp() { //Front -> Top -> Rear -> Bottom -> Front - m_cube->rotateUp(); + std::pair newDirs; + newDirs = getDirsFromFront("Bottom"); + DrawProjGroupItem* anchor = getAnchor(); + anchor->Direction.setValue(newDirs.first); + anchor->RotationVector.setValue(newDirs.second); updateSecondaryDirs(); } void DrawProjGroup::rotateDown() { //Front -> Bottom -> Rear -> Top -> Front - m_cube->rotateDown(); + std::pair newDirs; + newDirs = getDirsFromFront("Top"); + DrawProjGroupItem* anchor = getAnchor(); + anchor->Direction.setValue(newDirs.first); + anchor->RotationVector.setValue(newDirs.second); updateSecondaryDirs(); } void DrawProjGroup::spinCW() { //Top -> Right -> Bottom -> Left -> Top - m_cube->spinCW(); + DrawProjGroupItem* anchor = getAnchor(); + double angle = M_PI / 2.0; + Base::Vector3d org(0.0,0.0,0.0); + Base::Vector3d curRot = anchor->RotationVector.getValue(); + Base::Vector3d curDir = anchor->Direction.getValue(); + Base::Vector3d newRot = DrawUtil::vecRotate(curRot,-angle,curDir,org); + anchor->RotationVector.setValue(newRot); updateSecondaryDirs(); } void DrawProjGroup::spinCCW() { //Top -> Left -> Bottom -> Right -> Top - m_cube->spinCCW(); + DrawProjGroupItem* anchor = getAnchor(); + double angle = M_PI / 2.0; + Base::Vector3d org(0.0,0.0,0.0); + Base::Vector3d curRot = anchor->RotationVector.getValue(); + Base::Vector3d curDir = anchor->Direction.getValue(); + Base::Vector3d newRot = DrawUtil::vecRotate(curRot,angle,curDir,org); + anchor->RotationVector.setValue(newRot); + updateSecondaryDirs(); } diff --git a/src/Mod/TechDraw/App/DrawProjGroup.h b/src/Mod/TechDraw/App/DrawProjGroup.h index b25b85982a..5a807f7ca9 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.h +++ b/src/Mod/TechDraw/App/DrawProjGroup.h @@ -32,14 +32,12 @@ #include #include -//#include "Cube.h" #include "DrawViewCollection.h" namespace TechDraw { class DrawProjGroupItem; -class Cube; /** * Class super-container for managing a collection of DrawProjGroupItem @@ -64,8 +62,6 @@ public: App::PropertyFloat spacingY; App::PropertyLink Anchor; /// Anchor Element to align views to - App::PropertyVectorList CubeDirs; - App::PropertyVectorList CubeRotations; Base::BoundBox3d getBoundingBox() const; double calculateAutomaticScale() const; @@ -116,9 +112,10 @@ public: void setAnchorDirection(Base::Vector3d dir); Base::Vector3d getAnchorDirection(void); TechDraw::DrawProjGroupItem* getAnchor(void); + std::pair getDirsFromFront(DrawProjGroupItem* view); + std::pair getDirsFromFront(std::string viewType); void updateSecondaryDirs(); - void resetCube(void); void rotateRight(void); void rotateLeft(void); @@ -166,11 +163,8 @@ protected: TechDraw::DrawPage * getPage(void) const; void updateChildren(void); void updateChildrenSource(void); - void setPropsFromCube(void); - void setCubeFromProps(void); int getViewIndex(const char *viewTypeCStr) const; - - TechDraw::Cube* m_cube; + }; } //namespace TechDraw diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp index 2cd635e5a6..fdc9201a96 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp @@ -27,6 +27,8 @@ #endif #include +#include +#include #include #include @@ -63,8 +65,8 @@ DrawProjGroupItem::DrawProjGroupItem(void) ADD_PROPERTY_TYPE(RotationVector ,(1.0,0.0,0.0) ,"Base",App::Prop_None,"Controls rotation of item in view. "); //projection group controls these - Direction.setStatus(App::Property::ReadOnly,true); - RotationVector.setStatus(App::Property::ReadOnly,true); +// Direction.setStatus(App::Property::ReadOnly,true); +// RotationVector.setStatus(App::Property::ReadOnly,true); Scale.setStatus(App::Property::ReadOnly,true); ScaleType.setValue("Custom"); ScaleType.setStatus(App::Property::ReadOnly,true); @@ -98,6 +100,15 @@ DrawProjGroupItem::~DrawProjGroupItem() App::DocumentObjectExecReturn *DrawProjGroupItem::execute(void) { + if (DrawUtil::checkParallel(Direction.getValue(), + RotationVector.getValue())) { + Base::Console().Message("TRACE - DPGI::execute - Projdir: %s X: %s\n", + TechDraw::DrawUtil::formatVector(Direction.getValue()).c_str(), + TechDraw::DrawUtil::formatVector(RotationVector.getValue()).c_str()); + + return new App::DocumentObjectExecReturn("DPGI: Direction and RotationVector are parallel"); + } + App::DocumentObjectExecReturn * ret = DrawViewPart::execute(); delete ret; @@ -160,21 +171,43 @@ bool DrawProjGroupItem::isAnchor(void) return result; } +/// get a coord system aligned with Direction and Rotation Vector gp_Ax2 DrawProjGroupItem::getViewAxis(const Base::Vector3d& pt, const Base::Vector3d& axis, const bool flip) const { + (void) flip; gp_Ax2 viewAxis; Base::Vector3d x = RotationVector.getValue(); Base::Vector3d nx = x; x.Normalize(); Base::Vector3d na = axis; na.Normalize(); - viewAxis = TechDrawGeometry::getViewAxis(pt,axis,flip); //default orientation - if (!DrawUtil::checkParallel(nx,na)) { //!parallel/antiparallel - viewAxis = TechDrawGeometry::getViewAxis(pt,axis,x,flip); + if (DrawUtil::checkParallel(nx,na)) { + Base::Console().Warning("DPGI::getVA - axis and X parallel. using defaults\n"); + viewAxis = TechDrawGeometry::getViewAxis(pt,axis,false); + } else { + viewAxis = TechDrawGeometry::getViewAxis(pt,na,nx,false); } +// gp_Dir va_Main = viewAxis.Direction(); +// gp_Dir va_X = viewAxis.XDirection(); +// gp_Ax3 R3; +// gp_Ax3 viewCS(viewAxis); +// gp_Trsf txTo, txFrom; +// txTo.SetTransformation(R3,viewCS); +// txFrom = txTo.Inverted(); +// gp_Dir dirFrom = va_Main.Transformed(txFrom); +// gp_Dir dirTo = va_Main.Transformed(txTo); +// Base::Console().Message("TRACE - DPGI::getVA - dirFrom: %s dirTo: %s\n", +// DrawUtil::formatVector(dirFrom).c_str(), +// DrawUtil::formatVector(dirTo).c_str()); +// gp_Dir xFrom = va_X.Transformed(txFrom); +// gp_Dir xTo = va_X.Transformed(txTo); +// Base::Console().Message("TRACE - DPGI::getVA - xFrom: %s xTo: %s\n", +// DrawUtil::formatVector(xFrom).c_str(), +// DrawUtil::formatVector(xTo).c_str()); + return viewAxis; } diff --git a/src/Mod/TechDraw/App/DrawUtil.cpp b/src/Mod/TechDraw/App/DrawUtil.cpp index 3bad4b48b8..562e464a11 100644 --- a/src/Mod/TechDraw/App/DrawUtil.cpp +++ b/src/Mod/TechDraw/App/DrawUtil.cpp @@ -1,4 +1,3 @@ - /*************************************************************************** * Copyright (c) 2015 WandererFan * * * @@ -38,7 +37,9 @@ #include #include +#include #include +#include #include #include #include @@ -50,6 +51,10 @@ #include #include #include +#include +#include +#include +#include #endif @@ -59,6 +64,10 @@ #include #include +#include +#include + +#include "GeometryObject.h" #include "DrawUtil.h" using namespace TechDraw; @@ -288,6 +297,27 @@ std::string DrawUtil::formatVector(const Base::Vector2d& v) return result; } +std::string DrawUtil::formatVector(const gp_Dir& v) +{ + std::string result; + std::stringstream builder; + builder << std::fixed << std::setprecision(3) ; + builder << " (" << v.X() << "," << v.Y() << "," << v.Z() << ") "; + result = builder.str(); + return result; +} + +std::string DrawUtil::formatVector(const gp_Vec& v) +{ + std::string result; + std::stringstream builder; + builder << std::fixed << std::setprecision(3) ; + builder << " (" << v.X() << "," << v.Y() << "," << v.Z() << ") "; + result = builder.str(); + return result; +} + + //! compare 2 vectors for sorting - true if v1 < v2 bool DrawUtil::vectorLess(const Base::Vector3d& v1, const Base::Vector3d& v2) { diff --git a/src/Mod/TechDraw/App/DrawUtil.h b/src/Mod/TechDraw/App/DrawUtil.h index a54f6c0912..e2a1d0f04d 100644 --- a/src/Mod/TechDraw/App/DrawUtil.h +++ b/src/Mod/TechDraw/App/DrawUtil.h @@ -29,6 +29,8 @@ #include #include +#include +#include #include #include #include @@ -36,10 +38,13 @@ #include #include +#include #include #include #include +#include + #include "LineGroup.h" #define VERTEXTOLERANCE (2.0 * Precision::Confusion()) @@ -65,6 +70,8 @@ class TechDrawExport DrawUtil { static Base::Vector3d vertex2Vector(const TopoDS_Vertex& v); static std::string formatVector(const Base::Vector3d& v); static std::string formatVector(const Base::Vector2d& v); + static std::string formatVector(const gp_Dir& v); + static std::string formatVector(const gp_Vec& v); static bool vectorLess(const Base::Vector3d& v1, const Base::Vector3d& v2); static Base::Vector3d toR3(const gp_Ax2 fromSystem, const Base::Vector3d fromPoint); static bool checkParallel(const Base::Vector3d v1, const Base::Vector3d v2, double tolerance = FLT_EPSILON); @@ -83,7 +90,6 @@ class TechDrawExport DrawUtil { static Base::Vector3d Intersect2d(Base::Vector3d p1, Base::Vector3d d1, Base::Vector3d p2, Base::Vector3d d2); - //debugging routines static void dumpVertexes(const char* text, const TopoDS_Shape& s); static void dumpEdge(char* label, int i, TopoDS_Edge e); diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index c3b04c7eb2..e674daad80 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -129,7 +129,8 @@ DrawViewPart::DrawViewPart(void) : geometryObject(0) //properties that affect Geometry ADD_PROPERTY_TYPE(Source ,(0),group,App::Prop_None,"3D Shape to view"); Source.setScope(App::LinkScope::Global); - ADD_PROPERTY_TYPE(Direction ,(0,0,1.0) ,group,App::Prop_None,"Projection direction. The direction you are looking from."); + ADD_PROPERTY_TYPE(Direction ,(0.0,-1.0,0.0), + group,App::Prop_None,"Projection direction. The direction you are looking from."); ADD_PROPERTY_TYPE(Perspective ,(false),group,App::Prop_None,"Perspective(true) or Orthographic(false) projection"); ADD_PROPERTY_TYPE(Focus,(defDist),group,App::Prop_None,"Perspective view focus distance"); @@ -248,19 +249,18 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) inputCenter = TechDrawGeometry::findCentroid(shape, Direction.getValue()); shapeCentroid = Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()); - TopoDS_Shape mirroredShape; mirroredShape = TechDrawGeometry::mirrorShape(shape, inputCenter, getScale()); - gp_Ax2 viewAxis = getViewAxis(shapeCentroid,Direction.getValue()); - if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { + gp_Ax2 viewAxis = getViewAxis(shapeCentroid,Direction.getValue()); + if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { mirroredShape = TechDrawGeometry::rotateShape(mirroredShape, viewAxis, Rotation.getValue()); } - geometryObject = buildGeometryObject(mirroredShape,viewAxis); + geometryObject = buildGeometryObject(mirroredShape,viewAxis); #if MOD_TECHDRAW_HANDLE_FACES if (handleFaces() && !geometryObject->usePolygonHLR()) { @@ -690,7 +690,14 @@ gp_Ax2 DrawViewPart::getViewAxis(const Base::Vector3d& pt, const Base::Vector3d& axis, const bool flip) const { - gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(pt,axis,flip); + gp_Ax2 viewAxis = TechDrawGeometry::getViewAxis(pt,axis,flip); + + //put X dir of viewAxis on other side to get view right side up + gp_Ax1 rotAxis(viewAxis.Location(),viewAxis.Direction()); + gp_Dir xDir = viewAxis.XDirection(); + gp_Dir newX = xDir.Rotated(rotAxis, M_PI); + viewAxis.SetXDirection(newX); + return viewAxis; } diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index acbcd449d2..71ac3ab9fe 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -161,6 +161,18 @@ void GeometryObject::clear() void GeometryObject::projectShape(const TopoDS_Shape& input, const gp_Ax2 viewAxis) { + gp_Pnt org(0.0,0.0,0.0); + gp_Dir stdY(0.0,1.0,0.0); + gp_Dir stdX(1.0,0.0,0.0); + + gp_Ax2 yPlane(org,stdY,stdX); //XZ plane + gp_Dir va_Main = viewAxis.Direction(); + gp_Dir dirRev = va_Main.Mirrored(yPlane); + gp_Dir va_X = viewAxis.XDirection(); + gp_Dir xRev = va_X.Mirrored(yPlane); + + gp_Ax2 projAxis(org,dirRev,xRev); + // Clear previous Geometry clear(); @@ -172,10 +184,10 @@ void GeometryObject::projectShape(const TopoDS_Shape& input, brep_hlr->Add(input, m_isoCount); if (m_isPersp) { double fLength = std::max(Precision::Confusion(),m_focus); - HLRAlgo_Projector projector( viewAxis, fLength ); + HLRAlgo_Projector projector( projAxis, fLength ); brep_hlr->Projector(projector); } else { - HLRAlgo_Projector projector( viewAxis ); + HLRAlgo_Projector projector( projAxis ); brep_hlr->Projector(projector); } brep_hlr->Update(); @@ -543,21 +555,20 @@ bool GeometryObject::findVertex(Base::Vector2d v) /// utility non-class member functions //! gets a coordinate system that matches view system used in 3D with +Z up (or +Y up if necessary) //! used for individual views, but not secondary views in projection groups +//! flip determines Y mirror or not. +// getViewAxis 1 gp_Ax2 TechDrawGeometry::getViewAxis(const Base::Vector3d origin, const Base::Vector3d& direction, const bool flip) { + (void) flip; gp_Pnt inputCenter(origin.x,origin.y,origin.z); Base::Vector3d stdZ(0.0,0.0,1.0); Base::Vector3d flipDirection(direction.x,-direction.y,direction.z); - if (!flip) { - flipDirection = Base::Vector3d(direction.x,direction.y,direction.z); - } + flipDirection = Base::Vector3d(direction.x,direction.y,direction.z); Base::Vector3d cross = flipDirection; - //special cases - if ((flipDirection - stdZ).Length() < Precision::Confusion()) { - cross = Base::Vector3d(1.0,0.0,0.0); - } else if ((flipDirection - (stdZ * -1.0)).Length() < Precision::Confusion()) { + //special case + if (TechDraw::DrawUtil::checkParallel(flipDirection, stdZ)) { cross = Base::Vector3d(1.0,0.0,0.0); } else { cross.Normalize(); @@ -566,30 +577,36 @@ gp_Ax2 TechDrawGeometry::getViewAxis(const Base::Vector3d origin, gp_Ax2 viewAxis; viewAxis = gp_Ax2(inputCenter, gp_Dir(flipDirection.x, flipDirection.y, flipDirection.z), -// gp_Dir(1.0, 1.0, 0.0)); gp_Dir(cross.x, cross.y, cross.z)); return viewAxis; } //! gets a coordinate system specified by Z and X directions +//getViewAxis 2 gp_Ax2 TechDrawGeometry::getViewAxis(const Base::Vector3d origin, const Base::Vector3d& direction, const Base::Vector3d& xAxis, const bool flip) { + (void) flip; gp_Pnt inputCenter(origin.x,origin.y,origin.z); - Base::Vector3d flipDirection(direction.x,-direction.y,direction.z); - if (!flip) { - flipDirection = Base::Vector3d(direction.x,direction.y,direction.z); - } + Base::Vector3d projDir(direction.x,direction.y,direction.z); + gp_Ax2 viewAxis; - viewAxis = gp_Ax2(inputCenter, - gp_Dir(flipDirection.x, flipDirection.y, flipDirection.z), - gp_Dir(xAxis.x, xAxis.y, xAxis.z)); + + if (TechDraw::DrawUtil::checkParallel(projDir, xAxis)) { + Base::Console().Warning("GO::getViewAxis2 - direction and axis parallel - using default VA\n"); + viewAxis = gp_Ax2(inputCenter, + gp_Dir(projDir.x, projDir.y, projDir.z)); + + } else { + viewAxis = gp_Ax2(inputCenter, + gp_Dir(projDir.x, projDir.y, projDir.z), + gp_Dir(xAxis.x, xAxis.y, xAxis.z)); + } return viewAxis; } -//TODO: cardinal directions don't seem to affect result. is this right? //! Returns the centroid of shape, as viewed according to direction gp_Pnt TechDrawGeometry::findCentroid(const TopoDS_Shape &shape, const Base::Vector3d &direction) diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 292008f26b..f946fc4627 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -67,6 +67,7 @@ #include #include #include +#include #include #include "DrawGuiUtil.h" @@ -264,6 +265,7 @@ void CmdTechDrawNewView::activated(int iMsg) if (!page) { return; } + std::string PageName = page->getNameInDocument(); std::vector shapes = getSelection().getObjectsOfType(App::GeoFeature::getClassTypeId()); std::vector groups = getSelection().getObjectsOfType(App::DocumentObjectGroup::getClassTypeId()); @@ -276,8 +278,29 @@ void CmdTechDrawNewView::activated(int iMsg) if (!groups.empty()) { shapes.insert(shapes.end(),groups.begin(),groups.end()); } - - std::string PageName = page->getNameInDocument(); + + //set projection direction from selected Face + //use first object with a face selected + std::vector selection = getSelection().getSelectionEx(); + Part::Feature* partFeat = 0; + std::vector SubNames; + std::string faceName; + bool subFound = false; + std::vector::iterator itSel = selection.begin(); + for (; itSel != selection.end(); itSel++) { + if ((*itSel).getObject()->isDerivedFrom(Part::Feature::getClassTypeId())) { + partFeat = static_cast ((*itSel).getObject()); + SubNames = (*itSel).getSubNames(); + if (!SubNames.empty()) { + faceName = SubNames.front(); + if (TechDraw::DrawUtil::getGeomTypeFromName(faceName) == "Face") { + subFound = true; + break; + } + } + } + } + Base::Vector3d projDir; Gui::WaitCursor wc; openCommand("Create view"); @@ -290,6 +313,19 @@ void CmdTechDrawNewView::activated(int iMsg) } dvp->Source.setValues(shapes); doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); + if (subFound) { + std::pair dirs = DrawGuiUtil::getProjDirFromFace(partFeat,faceName); + projDir = dirs.first; + doCommand(Doc,"App.activeDocument().%s.Direction = FreeCAD.Vector(%.3f,%.3f,%.3f)", + FeatName.c_str(), projDir.x,projDir.y,projDir.z); + doCommand(Doc,"App.activeDocument().%s.recompute()", FeatName.c_str()); + } else { + std::pair dirs = DrawGuiUtil::get3DDirAndRot(); + projDir = dirs.first; + doCommand(Doc,"App.activeDocument().%s.Direction = FreeCAD.Vector(%.3f,%.3f,%.3f)", + FeatName.c_str(), projDir.x,projDir.y,projDir.z); + doCommand(Doc,"App.activeDocument().%s.recompute()", FeatName.c_str()); + } updateActive(); commitCommand(); } @@ -463,6 +499,7 @@ void CmdTechDrawProjGroup::activated(int iMsg) if (!page) { return; } + std::string PageName = page->getNameInDocument(); std::vector shapes = getSelection().getObjectsOfType(App::GeoFeature::getClassTypeId()); std::vector groups = getSelection().getObjectsOfType(App::DocumentObjectGroup::getClassTypeId()); @@ -476,8 +513,29 @@ void CmdTechDrawProjGroup::activated(int iMsg) shapes.insert(shapes.end(),groups.begin(),groups.end()); } - std::string PageName = page->getNameInDocument(); + //set projection direction from selected Face + //use first object with a face selected + std::vector selection = getSelection().getSelectionEx(); + Part::Feature* partFeat = 0; + std::vector SubNames; + std::string faceName; + bool subFound = false; + std::vector::iterator itSel = selection.begin(); + for (; itSel != selection.end(); itSel++) { + if ((*itSel).getObject()->isDerivedFrom(Part::Feature::getClassTypeId())) { + partFeat = static_cast ((*itSel).getObject()); + SubNames = (*itSel).getSubNames(); + if (!SubNames.empty()) { + faceName = SubNames.front(); + if (TechDraw::DrawUtil::getGeomTypeFromName(faceName) == "Face") { + subFound = true; + break; + } + } + } + } + Base::Vector3d projDir; Gui::WaitCursor wc; openCommand("Create Projection Group"); @@ -489,6 +547,24 @@ void CmdTechDrawProjGroup::activated(int iMsg) auto multiView( static_cast(docObj) ); multiView->Source.setValues(shapes); + if (subFound) { + std::pair dirs = DrawGuiUtil::getProjDirFromFace(partFeat,faceName); + doCommand(Doc,"App.activeDocument().%s.Anchor.Direction = FreeCAD.Vector(%.3f,%.3f,%.3f)", + multiViewName.c_str(), dirs.first.x,dirs.first.y,dirs.first.z); + doCommand(Doc,"App.activeDocument().%s.Anchor.RotationVector = FreeCAD.Vector(%.3f,%.3f,%.3f)", + multiViewName.c_str(), dirs.second.x,dirs.second.y,dirs.second.z); + getDocument()->setStatus(App::Document::Status::SkipRecompute, false); + doCommand(Doc,"App.activeDocument().%s.Anchor.recompute()", multiViewName.c_str()); + } else { + std::pair dirs = DrawGuiUtil::get3DDirAndRot(); + getDocument()->setStatus(App::Document::Status::SkipRecompute, true); + doCommand(Doc,"App.activeDocument().%s.Anchor.Direction = FreeCAD.Vector(%.3f,%.3f,%.3f)", + multiViewName.c_str(), dirs.first.x,dirs.first.y,dirs.first.z); + doCommand(Doc,"App.activeDocument().%s.Anchor.RotationVector = FreeCAD.Vector(%.3f,%.3f,%.3f)", + multiViewName.c_str(), dirs.second.x,dirs.second.y,dirs.second.z); + getDocument()->setStatus(App::Document::Status::SkipRecompute, false); + doCommand(Doc,"App.activeDocument().%s.Anchor.recompute()", multiViewName.c_str()); + } //updateActive(); //exec all pending actions, but there's nothing to do here. commitCommand(); //write the undo diff --git a/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp b/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp index 7a942c75f0..f0ee6f5cfb 100644 --- a/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp +++ b/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp @@ -36,6 +36,14 @@ #endif +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -51,6 +59,11 @@ #include #include #include +#include +#include +#include + +#include #include #include @@ -67,6 +80,7 @@ #include "DrawGuiUtil.h" using namespace TechDrawGui; +using namespace TechDraw; //=========================================================================== // validate helper routines @@ -187,3 +201,87 @@ void DrawGuiUtil::dumpPointF(const char* text, const QPointF& p) Base::Console().Message("DUMP - dumpPointF - %s\n",text); Base::Console().Message("Point: (%.3f, %.3f)\n",p.x(),p.y()); } + + +std::pair DrawGuiUtil::get3DDirAndRot() +{ + std::pair result; + Base::Vector3d viewDir(0.0,-1.0,0.0); //default to front + Base::Vector3d viewUp(0.0,0.0,1.0); //default to top + Base::Vector3d viewRight(1.0,0.0,0.0); //default to right + std::list mdis = Gui::Application::Instance->activeDocument()->getMDIViews(); + Gui::View3DInventor *view; + Gui::View3DInventorViewer *viewer = nullptr; + for (auto& m: mdis) { //find the 3D viewer + view = dynamic_cast(m); + if (view) { + viewer = view->getViewer(); + break; + } + } + if (!viewer) { + Base::Console().Log("LOG - DrawGuiUtil could not find a 3D viewer\n"); + return std::make_pair( viewDir, viewRight); + } + + SbVec3f dvec = viewer->getViewDirection(); + SbVec3f upvec = viewer->getUpDirection(); + + viewDir = Base::Vector3d(dvec[0], dvec[1], dvec[2]); + viewUp = Base::Vector3d(upvec[0],upvec[1],upvec[2]); + Base::Vector3d dirXup = viewDir.Cross(viewUp); //dir X up should give local Right + + viewDir = viewDir * (-1.0); // Inventor dir is opposite TD projection dir + + result = std::make_pair(viewDir,dirXup); + return result; +} + +std::pair DrawGuiUtil::getProjDirFromFace(Part::Feature* obj, std::string faceName) +{ + std::pair d3Dirs = get3DDirAndRot(); + Base::Vector3d d3Up = (d3Dirs.first).Cross(d3Dirs.second); + std::pair dirs; + dirs.first = Base::Vector3d(0.0,0.0,1.0); //set a default + dirs.second = Base::Vector3d(1.0,0.0,0.0); + Base::Vector3d projDir, rotVec; + projDir = d3Dirs.first; + rotVec = d3Dirs.second; + + if (DrawUtil::getGeomTypeFromName(faceName) != "Face") { + Base::Console().Warning("getProjDirFromFace(%s) is not a Face\n",faceName.c_str()); + return dirs; + } + Part::TopoShape ts = obj->Shape.getShape(); + ts.setPlacement(obj->globalPlacement()); + TopoDS_Shape subShape = ts.getSubShape(faceName.c_str()); + + const TopoDS_Face& face = TopoDS::Face(subShape); + TopAbs_Orientation orient = face.Orientation(); + BRepAdaptor_Surface adapt(face); + + double u1 = adapt.FirstUParameter(); + double u2 = adapt.LastUParameter(); + double v1 = adapt.FirstVParameter(); + double v2 = adapt.LastVParameter(); + double uMid = (u1+u2)/2.0; + double vMid = (v1+v2)/2.0; + + BRepLProp_SLProps props(adapt,uMid,vMid,2,Precision::Confusion()); + if (props.IsNormalDefined()) { + gp_Dir vec = props.Normal(); + projDir = Base::Vector3d(vec.X(),vec.Y(),vec.Z()); + rotVec = projDir.Cross(d3Up); + if (orient != TopAbs_FORWARD) { + projDir = projDir * (-1.0); + } + } + else { + Base::Console().Log("Selected Face has no normal at midpoint\n"); + } + + dirs = std::make_pair(projDir,rotVec); + return dirs; +} + + diff --git a/src/Mod/TechDraw/Gui/DrawGuiUtil.h b/src/Mod/TechDraw/Gui/DrawGuiUtil.h index 46a5502cbd..3a08906f2d 100644 --- a/src/Mod/TechDraw/Gui/DrawGuiUtil.h +++ b/src/Mod/TechDraw/Gui/DrawGuiUtil.h @@ -26,6 +26,11 @@ #include #include #include +#include + +namespace Part { +class Feature; +} namespace TechDraw { class DrawPage; @@ -45,6 +50,9 @@ class TechDrawGuiExport DrawGuiUtil { static bool needView(Gui::Command* cmd, bool partOnly = true); static void dumpRectF(const char* text, const QRectF& r); static void dumpPointF(const char* text, const QPointF& p); + static std::pair get3DDirAndRot(); + static std::pair getProjDirFromFace(Part::Feature* obj, std::string faceName); + }; } //end namespace TechDrawGui diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.cpp b/src/Mod/TechDraw/Gui/TaskProjGroup.cpp index fb6f82abac..dcfacd5d59 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.cpp +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -97,10 +98,8 @@ 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))); +// //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))); @@ -126,13 +125,17 @@ TaskProjGroup::~TaskProjGroup() void TaskProjGroup::viewToggled(bool toggle) { + Gui::WaitCursor wc; bool changed = false; // Obtain name of checkbox QString viewName = sender()->objectName(); int index = viewName.mid(7).toInt(); const char *viewNameCStr = viewChkIndexToCStr(index); if ( toggle && !multiView->hasProjection( viewNameCStr ) ) { - (void) multiView->addProjection( viewNameCStr ); + (void) multiView->addProjection( viewNameCStr ); //maybe this should be send a message instead of blocking? +// Gui::Command::doCommand(Gui::Command::Doc, // Gui response is no faster with this. :( +// "App.activeDocument().%s.addProjection('%s')", +// multiView->getNameInDocument(), viewNameCStr); changed = true; } else if ( !toggle && multiView->hasProjection( viewNameCStr ) ) { multiView->removeProjection( viewNameCStr ); @@ -144,7 +147,7 @@ void TaskProjGroup::viewToggled(bool toggle) setFractionalScale(scale); } } - + wc.restoreCursor(); } void TaskProjGroup::rotateButtonClicked(void) @@ -171,37 +174,14 @@ void TaskProjGroup::rotateButtonClicked(void) } } -void TaskProjGroup::on3DClicked(void) -{ - Base::Console().Warning("TaskProjGroup - this function is temporarily unavailable\n"); -//TODO: how to set the DPG.Cube (or a brand new replacement Cube) to a specific orientation -// {10x(viewDirection + RotationVector)} given only the -// viewDirection + upDirection(!= RotationVector) of the front view? -// need to find the sequence of rotations Left/Right, Up/Down, CW/CCW -// from current orientation to desired orientation. - -// std::pair dir3D = get3DViewDir(); -// Base::Vector3d dir = dir3D.first; -// dir = DrawUtil::closestBasis(dir); -// Base::Vector3d up = dir3D.second; -// up = DrawUtil::closestBasis(up); +//void TaskProjGroup::onResetClicked(void) +//{ // TechDraw::DrawProjGroupItem* front = multiView->getProjItem("Front"); -// if (front) { //why "if front"??? -// multiView->setTable(dir,up); +// if (front) { // setUiPrimary(); // Gui::Command::updateActive(); // } -} - -void TaskProjGroup::onResetClicked(void) -{ - TechDraw::DrawProjGroupItem* front = multiView->getProjItem("Front"); - if (front) { - multiView->resetCube(); - setUiPrimary(); - Gui::Command::updateActive(); - } -} +//} void TaskProjGroup::projectionTypeChanged(int index) { @@ -463,41 +443,6 @@ void TaskProjGroup::setUiPrimary() ui->lePrimary->setText(formatVector(frontDir)); } - -//should return a configuration? frontdir,upDir mapped in DPG -std::pair TaskProjGroup::get3DViewDir() -{ - std::pair result; - Base::Vector3d viewDir(0.0,-1.0,0.0); //default to front - Base::Vector3d viewUp(0.0,0.0,1.0); //default to top - std::list mdis = Gui::Application::Instance->activeDocument()->getMDIViews(); - Gui::View3DInventor *view; - Gui::View3DInventorViewer *viewer = nullptr; - for (auto& m: mdis) { //find the 3D viewer - view = dynamic_cast(m); - if (view) { - viewer = view->getViewer(); - break; - } - } - if (!viewer) { - Base::Console().Log("LOG - TaskProjGroup could not find a 3D viewer\n"); - return std::make_pair( viewDir, viewUp); - } - - SbVec3f dvec = viewer->getViewDirection(); - SbVec3f upvec = viewer->getUpDirection(); - - viewDir = Base::Vector3d(dvec[0], dvec[1], dvec[2]); - viewUp = Base::Vector3d(upvec[0],upvec[1],upvec[2]); - viewDir *= -1.0; //Inventor dir is opposite TD dir, Inventor up is same as TD up - viewDir = DrawUtil::closestBasis(viewDir); - viewUp = DrawUtil::closestBasis(viewUp); - result = std::make_pair(viewDir,viewUp); - return result; -} - - QString TaskProjGroup::formatVector(Base::Vector3d v) { QString data = QString::fromLatin1("[%1 %2 %3]") diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.h b/src/Mod/TechDraw/Gui/TaskProjGroup.h index af62796571..5100495cbf 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.h +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.h @@ -75,8 +75,7 @@ protected Q_SLOTS: /// Requests appropriate rotation of our DrawProjGroup void rotateButtonClicked(void); - void on3DClicked(void); - void onResetClicked(void); +// void onResetClicked(void); void projectionTypeChanged(int index); void scaleTypeChanged(int index); @@ -91,7 +90,6 @@ protected: * between checkboxes and viewToggled() */ void setupViewCheckboxes(bool addConnections = false); - std::pair get3DViewDir(void); void setUiPrimary(void); QString formatVector(Base::Vector3d v); diff --git a/src/Mod/TechDraw/Gui/TaskProjGroup.ui b/src/Mod/TechDraw/Gui/TaskProjGroup.ui index bb2f1faf57..98ac68c0d5 100644 --- a/src/Mod/TechDraw/Gui/TaskProjGroup.ui +++ b/src/Mod/TechDraw/Gui/TaskProjGroup.ui @@ -7,7 +7,7 @@ 0 0 371 - 491 + 506 @@ -306,19 +306,6 @@ - - - - false - - - This function is temporarily unavailable. - - - Match 3D - - - @@ -340,15 +327,31 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - Return Primary Direction to Initial Value + + + Qt::Horizontal - - Reset + + + 40 + 20 + - +