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)
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#include <Mod/TechDraw/App/DrawViewDraft.h>
|
||||
#include <Mod/TechDraw/App/DrawViewMulti.h>
|
||||
#include <Mod/TechDraw/App/DrawViewDetail.h>
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
#include <Mod/TechDraw/Gui/QGVPage.h>
|
||||
|
||||
#include "DrawGuiUtil.h"
|
||||
@@ -264,6 +265,7 @@ void CmdTechDrawNewView::activated(int iMsg)
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
std::string PageName = page->getNameInDocument();
|
||||
|
||||
std::vector<App::DocumentObject*> shapes = getSelection().getObjectsOfType(App::GeoFeature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> 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<Gui::SelectionObject> selection = getSelection().getSelectionEx();
|
||||
Part::Feature* partFeat = 0;
|
||||
std::vector<std::string> SubNames;
|
||||
std::string faceName;
|
||||
bool subFound = false;
|
||||
std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
|
||||
for (; itSel != selection.end(); itSel++) {
|
||||
if ((*itSel).getObject()->isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
partFeat = static_cast<Part::Feature*> ((*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<Base::Vector3d,Base::Vector3d> 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<Base::Vector3d,Base::Vector3d> 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<App::DocumentObject*> shapes = getSelection().getObjectsOfType(App::GeoFeature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> 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<Gui::SelectionObject> selection = getSelection().getSelectionEx();
|
||||
Part::Feature* partFeat = 0;
|
||||
std::vector<std::string> SubNames;
|
||||
std::string faceName;
|
||||
bool subFound = false;
|
||||
std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
|
||||
for (; itSel != selection.end(); itSel++) {
|
||||
if ((*itSel).getObject()->isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
partFeat = static_cast<Part::Feature*> ((*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<TechDraw::DrawProjGroup *>(docObj) );
|
||||
multiView->Source.setValues(shapes);
|
||||
|
||||
if (subFound) {
|
||||
std::pair<Base::Vector3d,Base::Vector3d> 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<Base::Vector3d,Base::Vector3d> 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
|
||||
|
||||
|
||||
@@ -36,6 +36,14 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepLProp_SLProps.hxx>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
@@ -51,6 +59,11 @@
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/MDIView.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
|
||||
#include <Inventor/SbVec3f.h>
|
||||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
#include <Mod/Part/App/Part2DObject.h>
|
||||
@@ -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<Base::Vector3d,Base::Vector3d> DrawGuiUtil::get3DDirAndRot()
|
||||
{
|
||||
std::pair<Base::Vector3d,Base::Vector3d> 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<Gui::MDIView*> mdis = Gui::Application::Instance->activeDocument()->getMDIViews();
|
||||
Gui::View3DInventor *view;
|
||||
Gui::View3DInventorViewer *viewer = nullptr;
|
||||
for (auto& m: mdis) { //find the 3D viewer
|
||||
view = dynamic_cast<Gui::View3DInventor*>(m);
|
||||
if (view) {
|
||||
viewer = view->getViewer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!viewer) {
|
||||
Base::Console().Log("LOG - 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<Base::Vector3d,Base::Vector3d> DrawGuiUtil::getProjDirFromFace(Part::Feature* obj, std::string faceName)
|
||||
{
|
||||
std::pair<Base::Vector3d,Base::Vector3d> d3Dirs = get3DDirAndRot();
|
||||
Base::Vector3d d3Up = (d3Dirs.first).Cross(d3Dirs.second);
|
||||
std::pair<Base::Vector3d,Base::Vector3d> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
#include <string>
|
||||
#include <QRectF>
|
||||
#include <QPointF>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
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<Base::Vector3d,Base::Vector3d> get3DDirAndRot();
|
||||
static std::pair<Base::Vector3d,Base::Vector3d> getProjDirFromFace(Part::Feature* obj, std::string faceName);
|
||||
|
||||
};
|
||||
|
||||
} //end namespace TechDrawGui
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
#include <Inventor/SbVec3f.h>
|
||||
|
||||
@@ -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<Base::Vector3d,Base::Vector3d> 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<Base::Vector3d,Base::Vector3d> TaskProjGroup::get3DViewDir()
|
||||
{
|
||||
std::pair<Base::Vector3d,Base::Vector3d> 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<MDIView*> mdis = Gui::Application::Instance->activeDocument()->getMDIViews();
|
||||
Gui::View3DInventor *view;
|
||||
Gui::View3DInventorViewer *viewer = nullptr;
|
||||
for (auto& m: mdis) { //find the 3D viewer
|
||||
view = dynamic_cast<Gui::View3DInventor*>(m);
|
||||
if (view) {
|
||||
viewer = view->getViewer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!viewer) {
|
||||
Base::Console().Log("LOG - TaskProjGroup could not find a 3D viewer\n");
|
||||
return 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]")
|
||||
|
||||
@@ -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<Base::Vector3d,Base::Vector3d> get3DViewDir(void);
|
||||
void setUiPrimary(void);
|
||||
QString formatVector(Base::Vector3d v);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>371</width>
|
||||
<height>491</height>
|
||||
<height>506</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -306,19 +306,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="but3D">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>This function is temporarily unavailable.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Match 3D</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="butDownRotate">
|
||||
<property name="toolTip">
|
||||
@@ -340,15 +327,31 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="butReset">
|
||||
<property name="toolTip">
|
||||
<string>Return Primary Direction to Initial Value</string>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user