diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index 23ed8d86bd..df36e8450a 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -270,13 +270,14 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) m_cutShape = rawShape; gp_Pnt inputCenter; + gp_Ax2 viewAxis; try { inputCenter = TechDraw::findCentroid(rawShape, - Direction.getValue()); + Direction.getValue()); //?? TopoDS_Shape mirroredShape = TechDraw::mirrorShape(rawShape, inputCenter, getScale()); - gp_Ax2 viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue()); + viewAxis = getSectionCS(SectionDirection.getValueAsString()); if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { mirroredShape = TechDraw::rotateShape(mirroredShape, viewAxis, @@ -298,7 +299,7 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) TopoDS_Shape mirroredSection = TechDraw::mirrorShape(sectionCompound, inputCenter, getScale()); - gp_Ax2 viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue()); +// gp_Ax2 viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue()); if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) { mirroredSection = TechDraw::rotateShape(mirroredSection, viewAxis, @@ -415,12 +416,13 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face, gp_Pnt faceCenter, const Base::Vector3d &direction) { + (void) direction; if(face.IsNull()) { throw Base::ValueError("DrawViewSection::projectFace - input Face is NULL"); } Base::Vector3d origin(faceCenter.X(),faceCenter.Y(),faceCenter.Z()); - gp_Ax2 viewAxis = getViewAxis(origin,direction); + gp_Ax2 viewAxis = getSectionCS(SectionDirection.getValueAsString()); HLRBRep_Algo *brep_hlr = new HLRBRep_Algo(); brep_hlr->Add(face); @@ -526,19 +528,16 @@ bool DrawViewSection::isReallyInBox (const gp_Pnt p, const Bnd_Box& bb) const return !bb.IsOut(p); } -//! calculate the section Normal/Projection Direction given baseView projection direction and section name +//! calculate the section Normal/Projection Direction given section name +//TODO: this should take base view rotation into account. Base::Vector3d DrawViewSection::getSectionVector (const std::string sectionName) { +// Base::Console().Message("DVS::getSectionVector(%s) - %s\n", sectionName.c_str(), getNameInDocument()); Base::Vector3d result; Base::Vector3d stdX(1.0,0.0,0.0); Base::Vector3d stdY(0.0,1.0,0.0); Base::Vector3d stdZ(0.0,0.0,1.0); - double adjustAngle = 0.0; - if (getBaseDPGI() != nullptr) { - adjustAngle = getBaseDPGI()->getRotateAngle(); - } - Base::Vector3d view = getBaseDVP()->Direction.getValue(); view.Normalize(); Base::Vector3d left = view.Cross(stdZ); @@ -575,8 +574,101 @@ Base::Vector3d DrawViewSection::getSectionVector (const std::string sectionName) Base::Console().Log("Error - DVS::getSectionVector - bad sectionName: %s\n",sectionName.c_str()); result = stdZ; } - Base::Vector3d adjResult = DrawUtil::vecRotate(result,adjustAngle,view); - return adjResult; + return result; +} + +//! calculate the section Projection CS given section direction name +gp_Ax2 DrawViewSection::getSectionCS (const std::string dirName) +{ + Base::Vector3d view = getBaseDVP()->Direction.getValue(); + view.Normalize(); + + Base::Vector3d sectionOrg = SectionOrigin.getValue(); + gp_Ax2 baseCS = getBaseDVP()->getViewAxis(sectionOrg, + view); + + // cardinal: 0 - left, 1 - right, 2 - up, 3 - down + int cardinal = 0; + if (dirName == "Up") { + cardinal = 2; + } else if (dirName == "Down") { + cardinal = 3; + } else if (dirName == "Left") { + cardinal = 0; + } else if (dirName == "Right") { + cardinal = 1; + } + gp_Ax2 newCS = rotateCSCardinal(baseCS, cardinal); + return newCS; +} + + +//TODO: this should be able to handle arbitrary rotation of the CS +//TODO: this is useful beyond DVS. move to GO or DU or ??? +// or at least static in DVS. doesn't depend on DVS object +gp_Ax2 DrawViewSection::rotateCSCardinal(gp_Ax2 oldCS, int cardinal) +{ + // cardinal: 0 - left, 1 - right, 2 - up, 3 - down + // as in DVS::SectionDirection + gp_Pnt oldOrg = oldCS.Location(); + gp_Dir oldMain = oldCS.Direction(); + gp_Dir oldX = oldCS.XDirection(); + + gp_Ax1 rotAxis; + gp_Dir crossed; + gp_Ax2 newCS; + double angle; + + //Note: cardinal refers to the the motion of the viewer's head. When the head turns to + // the left, the "Direction" moves to the right! When the viewer's head moves to look up, + // the "Direction" moves down! + + switch (cardinal) { + case 0: //right + crossed = oldMain.Crossed(oldX); + rotAxis = gp_Ax1(oldOrg, crossed); + angle = 90.0 * M_PI / 180.0; + newCS = oldCS.Rotated(rotAxis, angle); + break; + case 1: //left + crossed = oldMain.Crossed(oldX); + rotAxis = gp_Ax1(oldOrg, crossed); + angle = -90.0 * M_PI / 180.0; + newCS = oldCS.Rotated(rotAxis, angle); + break; + case 2: // head looks up, so Direction(projection normal) points down + rotAxis = gp_Ax1(oldOrg, oldX); + angle = -90.0 * M_PI / 180.0; + newCS = oldCS.Rotated(rotAxis, angle); + break; + case 3: //down + rotAxis = gp_Ax1(oldOrg, oldX); //one of these should be -oldX? + angle = 90.0 * M_PI / 180.0; + newCS = oldCS.Rotated(rotAxis, angle); + break; + default: + newCS = oldCS; + break; + } + + return newCS; +} + +gp_Ax2 DrawViewSection::rotateCSArbitrary(gp_Ax2 oldCS, + Base::Vector3d axis, + double degAngle) +{ + gp_Ax2 newCS; + + gp_Pnt oldOrg = oldCS.Location(); + + gp_Dir gAxis(axis.x, axis.y, axis.z); + gp_Ax1 rotAxis = gp_Ax1(oldOrg, gAxis); + + double radAngle = degAngle * M_PI / 180.0; + + newCS = oldCS.Rotated(rotAxis, radAngle); + return newCS; } std::vector DrawViewSection::getDrawableLines(int i) diff --git a/src/Mod/TechDraw/App/DrawViewSection.h b/src/Mod/TechDraw/App/DrawViewSection.h index 4db327ede4..4acac38ac4 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.h +++ b/src/Mod/TechDraw/App/DrawViewSection.h @@ -39,6 +39,7 @@ class Bnd_Box; class gp_Pln; class gp_Pnt; class TopoDS_Face; +class gp_Ax2; namespace TechDraw { @@ -84,7 +85,14 @@ public: public: std::vector getFaceGeometry(); + Base::Vector3d getSectionVector (const std::string sectionName); + gp_Ax2 rotateCSCardinal(gp_Ax2 oldCS, int cardinal); + gp_Ax2 rotateCSArbitrary(gp_Ax2 oldCS, + Base::Vector3d axis, + double degAngle) ; + gp_Ax2 getSectionCS (const std::string dirName); + TechDraw::DrawViewPart* getBaseDVP(); TechDraw::DrawProjGroupItem* getBaseDPGI(); virtual void unsetupObject(); diff --git a/src/Mod/TechDraw/Gui/TaskSectionView.cpp b/src/Mod/TechDraw/Gui/TaskSectionView.cpp index 5450e8f16e..3f7a7e19bd 100644 --- a/src/Mod/TechDraw/Gui/TaskSectionView.cpp +++ b/src/Mod/TechDraw/Gui/TaskSectionView.cpp @@ -124,20 +124,17 @@ bool TaskSectionView::calcValues() if (ui->pb_Up->isChecked()) { sectionDir = "Up"; - sectionProjDir = m_section->getSectionVector(sectionDir); } else if (ui->pb_Down->isChecked()) { sectionDir = "Down"; - sectionProjDir = m_section->getSectionVector(sectionDir); } else if (ui->pb_Left->isChecked()) { sectionDir = "Left"; - sectionProjDir = m_section->getSectionVector(sectionDir); } else if (ui->pb_Right->isChecked()) { sectionDir = "Right"; - sectionProjDir = m_section->getSectionVector(sectionDir); } else { Base::Console().Message("Select a direction\n"); result = false; } + sectionProjDir = m_section->getSectionVector(sectionDir); sectionNormal = sectionProjDir; if (result) {