Use Face or 3D direction for View and ProjGroup
- use current 3D window direction as starting direction for DrawViewPart and ProjectionGroup - if a Face is selected, use Face normal as starting direction.
This commit is contained in:
@@ -96,8 +96,6 @@ SET(TechDraw_SRCS
|
||||
AppTechDrawPy.cpp
|
||||
DrawUtil.cpp
|
||||
DrawUtil.h
|
||||
Cube.cpp
|
||||
Cube.h
|
||||
HatchLine.cpp
|
||||
HatchLine.h
|
||||
PreCompiled.cpp
|
||||
|
||||
@@ -1,565 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2016 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
|
||||
#include "DrawUtil.h"
|
||||
#include "Cube.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
|
||||
//default starting dirs & rots
|
||||
const std::map<std::string,Base::Vector3d> 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<std::string,Base::Vector3d> 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<std::string, Base::Vector3d>::value_type("Bottom", b));
|
||||
m_mapCubeDir.insert(std::map<std::string, Base::Vector3d>::value_type("Front" , f));
|
||||
m_mapCubeDir.insert(std::map<std::string, Base::Vector3d>::value_type("Left" , l));
|
||||
m_mapCubeDir.insert(std::map<std::string, Base::Vector3d>::value_type("Rear" , k));
|
||||
m_mapCubeDir.insert(std::map<std::string, Base::Vector3d>::value_type("Right" , r));
|
||||
m_mapCubeDir.insert(std::map<std::string, Base::Vector3d>::value_type("Top" , t));
|
||||
|
||||
m_mapCubeRot.clear();
|
||||
m_mapCubeRot.insert(std::map<std::string, Base::Vector3d>::value_type("Bottom", br));
|
||||
m_mapCubeRot.insert(std::map<std::string, Base::Vector3d>::value_type("Front" , fr));
|
||||
m_mapCubeRot.insert(std::map<std::string, Base::Vector3d>::value_type("Left" , lr));
|
||||
m_mapCubeRot.insert(std::map<std::string, Base::Vector3d>::value_type("Rear" , kr));
|
||||
m_mapCubeRot.insert(std::map<std::string, Base::Vector3d>::value_type("Right" , rr));
|
||||
m_mapCubeRot.insert(std::map<std::string, Base::Vector3d>::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<std::string, Base::Vector3d> newDirs;
|
||||
for (auto& d: m_mapCubeDir) {
|
||||
Base::Vector3d v = rodrigues(d.second,angle,axis);
|
||||
newDirs.insert(std::map<std::string, Base::Vector3d>::value_type(d.first, v));
|
||||
}
|
||||
|
||||
std::map<std::string, Base::Vector3d> newRots;
|
||||
for (auto& r: m_mapCubeRot) {
|
||||
Base::Vector3d v = rodrigues(r.second,-angle,axis);
|
||||
newRots.insert(std::map<std::string, Base::Vector3d>::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<std::string, Base::Vector3d> newDirs;
|
||||
for (auto& d: m_mapCubeDir) {
|
||||
Base::Vector3d v = rodrigues(d.second,-angle,axis);
|
||||
newDirs.insert(std::map<std::string, Base::Vector3d>::value_type(d.first, v));
|
||||
}
|
||||
|
||||
std::map<std::string, Base::Vector3d> newRots;
|
||||
for (auto& r: m_mapCubeRot) {
|
||||
Base::Vector3d v = rodrigues(r.second,angle,axis);
|
||||
newRots.insert(std::map<std::string, Base::Vector3d>::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<std::string, Base::Vector3d> newDirs;
|
||||
for (auto& d: m_mapCubeDir) {
|
||||
Base::Vector3d v = rodrigues(d.second,-angle,axis);
|
||||
newDirs.insert(std::map<std::string, Base::Vector3d>::value_type(d.first, v));
|
||||
}
|
||||
|
||||
std::map<std::string, Base::Vector3d> newRots;
|
||||
for (auto& r: m_mapCubeRot) {
|
||||
Base::Vector3d v = rodrigues(r.second,angle,axis);
|
||||
newRots.insert(std::map<std::string, Base::Vector3d>::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<std::string, Base::Vector3d> newDirs;
|
||||
for (auto& d: m_mapCubeDir) {
|
||||
Base::Vector3d v = rodrigues(d.second,angle,axis);
|
||||
newDirs.insert(std::map<std::string, Base::Vector3d>::value_type(d.first, v));
|
||||
}
|
||||
|
||||
std::map<std::string, Base::Vector3d> newRots;
|
||||
for (auto& r: m_mapCubeRot) {
|
||||
Base::Vector3d v = rodrigues(r.second,-angle,axis);
|
||||
newRots.insert(std::map<std::string, Base::Vector3d>::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<std::string, Base::Vector3d> newDirs;
|
||||
for (auto& d: m_mapCubeDir) {
|
||||
Base::Vector3d v = rodrigues(d.second,-angle,axis);
|
||||
newDirs.insert(std::map<std::string, Base::Vector3d>::value_type(d.first, v));
|
||||
}
|
||||
std::map<std::string, Base::Vector3d> newRots;
|
||||
for (auto& r: m_mapCubeRot) {
|
||||
Base::Vector3d v = rodrigues(r.second,angle,axis);
|
||||
newRots.insert(std::map<std::string, Base::Vector3d>::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<std::string, Base::Vector3d> newDirs;
|
||||
for (auto& d: m_mapCubeDir) {
|
||||
Base::Vector3d v = rodrigues(d.second,angle,axis);
|
||||
newDirs.insert(std::map<std::string, Base::Vector3d>::value_type(d.first, v));
|
||||
}
|
||||
|
||||
std::map<std::string, Base::Vector3d> newRots;
|
||||
for (auto& r: m_mapCubeRot) {
|
||||
Base::Vector3d v = rodrigues(r.second,-angle,axis);
|
||||
newRots.insert(std::map<std::string, Base::Vector3d>::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<Base::Vector3d> Cube::getAllDirs(void)
|
||||
{
|
||||
std::vector<Base::Vector3d> result;
|
||||
for (auto& d: m_mapCubeDir) {
|
||||
Base::Vector3d v = d.second;
|
||||
result.push_back(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<Base::Vector3d> Cube::getAllRots(void)
|
||||
{
|
||||
std::vector<Base::Vector3d> result;
|
||||
for (auto& r: m_mapCubeRot) {
|
||||
Base::Vector3d v = r.second;
|
||||
result.push_back(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Cube::setAllDirs(std::vector<Base::Vector3d> 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<std::string, Base::Vector3d> newDirs;
|
||||
for (auto& d: m_mapCubeDir) {
|
||||
Base::Vector3d v = (*i);
|
||||
newDirs.insert(std::map<std::string, Base::Vector3d>::value_type(d.first, v));
|
||||
i++;
|
||||
}
|
||||
m_mapCubeDir = newDirs;
|
||||
}
|
||||
|
||||
void Cube::setAllRots(std::vector<Base::Vector3d> 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<std::string, Base::Vector3d> newRots;
|
||||
for (auto& r: m_mapCubeRot) {
|
||||
Base::Vector3d v = (*i);
|
||||
newRots.insert(std::map<std::string, Base::Vector3d>::value_type(r.first, v));
|
||||
i++;
|
||||
}
|
||||
m_mapCubeRot = newRots;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2016 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef _CUBE_H_
|
||||
#define _CUBE_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
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<Base::Vector3d> getAllDirs(void);
|
||||
std::vector<Base::Vector3d> getAllRots(void);
|
||||
void setAllDirs(std::vector<Base::Vector3d> dirs);
|
||||
void setAllRots(std::vector<Base::Vector3d> rots);
|
||||
|
||||
private:
|
||||
//the current state of the "cube"
|
||||
//the "cube" is always full - entries for every ortho position (6 total)
|
||||
std::map<std::string, Base::Vector3d> m_mapCubeDir;
|
||||
std::map<std::string, Base::Vector3d> m_mapCubeRot;
|
||||
|
||||
static const std::map<std::string,Base::Vector3d> m_viewDefault;
|
||||
static const std::map<std::string,Base::Vector3d> m_rotDefault;
|
||||
|
||||
//should be in drawutil?
|
||||
Base::Vector3d rodrigues(Base::Vector3d v,
|
||||
double angle,
|
||||
Base::Vector3d axis);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <Base/Matrix.h>
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
#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<Base::Vector3d,Base::Vector3d> 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<Base::Vector3d,Base::Vector3d> DrawProjGroup::getDirsFromFront(DrawProjGroupItem* view)
|
||||
{
|
||||
std::pair<Base::Vector3d,Base::Vector3d> result;
|
||||
std::string viewType = view->Type.getValueAsString();
|
||||
result = getDirsFromFront(viewType);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::pair<Base::Vector3d,Base::Vector3d> DrawProjGroup::getDirsFromFront(std::string viewType)
|
||||
{
|
||||
std::pair<Base::Vector3d,Base::Vector3d> 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<std::string, std::pair<Base::Vector3d,Base::Vector3d> > saveVals;
|
||||
std::string key;
|
||||
std::pair<Base::Vector3d, Base::Vector3d> data;
|
||||
for (auto& docObj: Views.getValues()) {
|
||||
Base::Vector3d newDir;
|
||||
Base::Vector3d newAxis;
|
||||
Base::Vector3d newRot;
|
||||
std::pair<Base::Vector3d,Base::Vector3d> newDirs;
|
||||
std::string pic;
|
||||
DrawProjGroupItem* v = static_cast<DrawProjGroupItem*>(docObj);
|
||||
ProjItemType t = static_cast<ProjItemType>(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<DrawProjGroupItem*>(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<Base::Vector3d,Base::Vector3d> 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<Base::Vector3d,Base::Vector3d> 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<Base::Vector3d,Base::Vector3d> 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<Base::Vector3d,Base::Vector3d> 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,14 +32,12 @@
|
||||
#include <Base/Matrix.h>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
//#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<Base::Vector3d,Base::Vector3d> getDirsFromFront(DrawProjGroupItem* view);
|
||||
std::pair<Base::Vector3d,Base::Vector3d> 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
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#endif
|
||||
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Writer.h>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2015 WandererFan <wandererfan@gmail.com> *
|
||||
* *
|
||||
@@ -38,7 +37,9 @@
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepExtrema_DistShapeShape.hxx>
|
||||
@@ -50,6 +51,10 @@
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <GeomLProp_SLProps.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepLProp_SLProps.hxx>
|
||||
#include <BRepGProp_Face.hxx>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -59,6 +64,10 @@
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <QByteArray>
|
||||
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
@@ -36,10 +38,13 @@
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Base/Tools2D.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/Matrix.h>
|
||||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user