| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <BRepBuilderAPI_MakeEdge.hxx> |
| | #include <BRepBndLib.hxx> |
| | #include <Bnd_Box.hxx> |
| | #include <TopoDS_Shape.hxx> |
| |
|
| | #include <BRepTools.hxx> |
| |
|
| | #include <Base/Console.h> |
| | #include <Base/Converter.h> |
| | #include <Base/Tools.h> |
| |
|
| | #include "CenterLine.h" |
| | #include "DrawUtil.h" |
| | #include "DrawViewPart.h" |
| | #include "Geometry.h" |
| | #include "CenterLinePy.h" |
| | #include "ShapeUtils.h" |
| |
|
| | using namespace TechDraw; |
| | using DU = DrawUtil; |
| |
|
| | TYPESYSTEM_SOURCE(TechDraw::CenterLine, Base::Persistence) |
| |
|
| | CenterLine::CenterLine() |
| | { |
| | m_start = Base::Vector3d(0.0, 0.0, 0.0); |
| | m_end = Base::Vector3d(0.0, 0.0, 0.0); |
| | m_mode = Mode::VERTICAL; |
| | m_hShift = 0.0; |
| | m_vShift = 0.0; |
| | m_rotate = 0.0; |
| | m_extendBy = 0.0; |
| | m_type = Type::FACE; |
| | m_flip2Line = false; |
| |
|
| | m_geometry = std::make_shared<TechDraw::BaseGeom> (); |
| |
|
| | initialize(); |
| | } |
| |
|
| | CenterLine::CenterLine(const TechDraw::CenterLine* cl) |
| | { |
| | m_start = cl->m_start; |
| | m_end = cl->m_end; |
| | m_mode = cl->m_mode; |
| | m_hShift = cl->m_hShift; |
| | m_vShift = cl->m_vShift; |
| | m_rotate = cl->m_rotate; |
| | m_extendBy = cl->m_extendBy; |
| | m_type = cl->m_type; |
| | m_flip2Line = cl->m_flip2Line; |
| |
|
| | m_geometry = cl->m_geometry; |
| |
|
| | initialize(); |
| | } |
| |
|
| | CenterLine::CenterLine(const TechDraw::BaseGeomPtr& bg, |
| | const Mode m, |
| | const double h, |
| | const double v, |
| | const double r, |
| | const double x) |
| | { |
| | m_start = bg->getStartPoint(); |
| | m_end = bg->getEndPoint(); |
| | m_mode = m; |
| | m_hShift = h; |
| | m_vShift = v; |
| | m_rotate = r; |
| | m_extendBy = x; |
| | m_type = Type::FACE; |
| | m_flip2Line = false; |
| |
|
| | m_geometry = bg; |
| |
|
| | initialize(); |
| | } |
| |
|
| | CenterLine::CenterLine(const Base::Vector3d& pt1, |
| | const Base::Vector3d& pt2, |
| | const Mode m, |
| | const double h, |
| | const double v, |
| | const double r, |
| | const double x) |
| | { |
| | m_start = pt1; |
| | m_end = pt2; |
| | m_mode = m; |
| | m_hShift = h; |
| | m_vShift = v; |
| | m_rotate = r; |
| | m_extendBy = x; |
| | m_type = Type::FACE; |
| | m_flip2Line = false; |
| |
|
| | m_geometry = BaseGeomPtrFromVectors(pt1, pt2); |
| |
|
| | initialize(); |
| |
|
| | } |
| |
|
| | CenterLine::~CenterLine() |
| | { |
| | } |
| |
|
| | void CenterLine::initialize() |
| | { |
| | m_geometry->setClassOfEdge(EdgeClass::HARD); |
| | m_geometry->setHlrVisible( true); |
| | m_geometry->setCosmetic(true); |
| | m_geometry->source(SourceType::CENTERLINE); |
| | m_geometry->setCosmeticTag(getTagAsString()); |
| | } |
| |
|
| | TechDraw::BaseGeomPtr CenterLine::BaseGeomPtrFromVectors(Base::Vector3d pt1, Base::Vector3d pt2) |
| | { |
| | |
| | Base::Vector3d p1 = DrawUtil::invertY(pt1); |
| | Base::Vector3d p2 = DrawUtil::invertY(pt2); |
| | gp_Pnt gp1(p1.x, p1.y, p1.z); |
| | gp_Pnt gp2(p2.x, p2.y, p2.z); |
| | TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp1, gp2); |
| | TechDraw::BaseGeomPtr bg = TechDraw::BaseGeom::baseFactory(e); |
| | return bg; |
| | } |
| |
|
| | CenterLine* CenterLine::CenterLineBuilder(const DrawViewPart* partFeat, |
| | const std::vector<std::string>& subNames, |
| | const Mode mode, |
| | const bool flip) |
| | { |
| | |
| | std::pair<Base::Vector3d, Base::Vector3d> ends; |
| | std::vector<std::string> faces; |
| | std::vector<std::string> edges; |
| | std::vector<std::string> verts; |
| |
|
| | std::string geomType = TechDraw::DrawUtil::getGeomTypeFromName(subNames.front()); |
| | Type type = Type::FACE; |
| | if (geomType == "Face") { |
| | type = Type::FACE; |
| | ends = TechDraw::CenterLine::calcEndPoints(partFeat, |
| | subNames, |
| | mode, |
| | 0.0, |
| | 0.0, 0.0, 0.0); |
| | faces = subNames; |
| | } else if (geomType == "Edge") { |
| | type = Type::EDGE; |
| | ends = TechDraw::CenterLine::calcEndPoints2Lines(partFeat, |
| | subNames, |
| | mode, |
| | 0.0, |
| | 0.0, 0.0, 0.0, flip); |
| | edges = subNames; |
| | } else if (geomType == "Vertex") { |
| | type = Type::VERTEX; |
| | ends = TechDraw::CenterLine::calcEndPoints2Points(partFeat, |
| | subNames, |
| | mode, |
| | 0.0, |
| | 0.0, 0.0, 0.0, flip); |
| | verts = subNames; |
| | } |
| | if ((ends.first).IsEqual(ends.second, Precision::Confusion())) { |
| | Base::Console().warning("CenterLineBuilder - endpoints are equal: %s\n", |
| | DrawUtil::formatVector(ends.first).c_str()); |
| | Base::Console().warning("CenterLineBuilder - check V/H/A and/or Flip parameters\n"); |
| | return nullptr; |
| | } |
| |
|
| | auto * cl = new TechDraw::CenterLine(ends.first, ends.second); |
| | cl->m_type = type; |
| | cl->m_mode = mode; |
| | cl->m_faces = faces; |
| | cl->m_edges = edges; |
| | cl->m_verts = verts; |
| | cl->m_flip2Line = flip; |
| | return cl; |
| | } |
| |
|
| | TechDraw::BaseGeomPtr CenterLine::scaledGeometry(const TechDraw::DrawViewPart* partFeat) |
| | { |
| | |
| | double scale = partFeat->getScale(); |
| | double viewAngleDeg = partFeat->Rotation.getValue(); |
| | std::pair<Base::Vector3d, Base::Vector3d> ends; |
| | try { |
| | if (m_faces.empty() && |
| | m_edges.empty() && |
| | m_verts.empty() ) { |
| | |
| | |
| | ends = calcEndPointsNoRef(m_start, m_end, scale, m_extendBy, |
| | m_hShift, m_vShift, m_rotate, viewAngleDeg); |
| | } else if (m_type == Type::FACE) { |
| | ends = calcEndPoints(partFeat, |
| | m_faces, |
| | m_mode, m_extendBy, |
| | m_hShift, m_vShift, m_rotate); |
| | } else if (m_type == Type::EDGE) { |
| | ends = calcEndPoints2Lines(partFeat, |
| | m_edges, |
| | m_mode, |
| | m_extendBy, |
| | m_hShift, m_vShift, m_rotate, m_flip2Line); |
| | } else if (m_type == Type::VERTEX) { |
| | ends = calcEndPoints2Points(partFeat, |
| | m_verts, |
| | m_mode, |
| | m_extendBy, |
| | m_hShift, m_vShift, m_rotate, m_flip2Line); |
| | } |
| | } |
| |
|
| | catch (...) { |
| | Base::Console().error("CL::scaledGeometry - failed to calculate endpoints!\n"); |
| | return nullptr; |
| | } |
| |
|
| | Base::Vector3d p1 = ends.first; |
| | Base::Vector3d p2 = ends.second; |
| | if (p1.IsEqual(p2, 0.00001)) { |
| | Base::Console().warning("Centerline endpoints are equal. Could not draw.\n"); |
| | |
| | return m_geometry; |
| | } |
| |
|
| | gp_Pnt gp1(p1.x, p1.y, p1.z); |
| | gp_Pnt gp2(p2.x, p2.y, p2.z); |
| | TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp1, gp2); |
| | TopoDS_Shape s = ShapeUtils::scaleShape(e, scale); |
| | TopoDS_Edge newEdge = TopoDS::Edge(s); |
| | TechDraw::BaseGeomPtr newGeom = TechDraw::BaseGeom::baseFactory(newEdge); |
| | newGeom->setClassOfEdge(EdgeClass::HARD); |
| | newGeom->setHlrVisible( true); |
| | newGeom->setCosmetic(true); |
| | newGeom->source(SourceType::CENTERLINE); |
| | newGeom->setCosmeticTag(getTagAsString()); |
| |
|
| | return newGeom; |
| | } |
| |
|
| | TechDraw::BaseGeomPtr CenterLine::scaledAndRotatedGeometry(TechDraw::DrawViewPart* partFeat) |
| | { |
| | |
| | double scale = partFeat->getScale(); |
| | double viewAngleDeg = partFeat->Rotation.getValue(); |
| | std::pair<Base::Vector3d, Base::Vector3d> ends; |
| | try { |
| | if (m_faces.empty() && |
| | m_edges.empty() && |
| | m_verts.empty() ) { |
| | |
| | |
| | ends = calcEndPointsNoRef(m_start, m_end, scale, m_extendBy, |
| | m_hShift, m_vShift, m_rotate, viewAngleDeg); |
| | } else if (m_type == Type::FACE) { |
| | ends = calcEndPoints(partFeat, |
| | m_faces, |
| | m_mode, m_extendBy, |
| | m_hShift, m_vShift, m_rotate); |
| | } else if (m_type == Type::EDGE) { |
| | ends = calcEndPoints2Lines(partFeat, |
| | m_edges, |
| | m_mode, |
| | m_extendBy, |
| | m_hShift, m_vShift, m_rotate, m_flip2Line); |
| | } else if (m_type == Type::VERTEX) { |
| | ends = calcEndPoints2Points(partFeat, |
| | m_verts, |
| | m_mode, |
| | m_extendBy, |
| | m_hShift, m_vShift, m_rotate, m_flip2Line); |
| | } |
| | } |
| |
|
| | catch (...) { |
| | Base::Console().error("CL::scaledGeometry - failed to calculate endpoints!\n"); |
| | return nullptr; |
| | } |
| |
|
| | |
| | Base::Vector3d p1 = ends.first; |
| | Base::Vector3d p2 = ends.second; |
| | if (p1.IsEqual(p2, 0.00001)) { |
| | Base::Console().warning("Centerline endpoints are equal. Could not draw.\n"); |
| | |
| | return m_geometry; |
| | } |
| |
|
| | TopoDS_Edge newEdge; |
| | if (getType() == Type::FACE ) { |
| | gp_Pnt gp1(Base::convertTo<gp_Pnt>(p1)); |
| | gp_Pnt gp2(Base::convertTo<gp_Pnt>(p2)); |
| | TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp1, gp2); |
| | |
| | TopoDS_Shape s = ShapeUtils::mirrorShape(e, gp_Pnt(0.0, 0.0, 0.0), scale); |
| | |
| | s = ShapeUtils::rotateShape(s, gp_Ax2(), - partFeat->Rotation.getValue()); |
| | newEdge = TopoDS::Edge(s); |
| | } else if (getType() == Type::EDGE || |
| | getType() == Type::VERTEX) { |
| | gp_Pnt gp1(Base::convertTo<gp_Pnt>(DU::invertY(p1 * scale))); |
| | gp_Pnt gp2(Base::convertTo<gp_Pnt>(DU::invertY(p2 * scale))); |
| | newEdge = BRepBuilderAPI_MakeEdge(gp1, gp2); |
| | } |
| |
|
| | TechDraw::BaseGeomPtr newGeom = TechDraw::BaseGeom::baseFactory(newEdge); |
| | if (!newGeom) { |
| | throw Base::RuntimeError("Failed to create center line"); |
| | } |
| | newGeom->setClassOfEdge(EdgeClass::HARD); |
| | newGeom->setHlrVisible( true); |
| | newGeom->setCosmetic(true); |
| | newGeom->source(SourceType::CENTERLINE); |
| | newGeom->setCosmeticTag(getTagAsString()); |
| |
|
| | return newGeom; |
| | } |
| |
|
| | std::string CenterLine::toString() const |
| | { |
| | std::stringstream ss; |
| | ss << m_start.x << ", " << |
| | m_start.y << ", " << |
| | m_start.z << ", " << |
| | m_end.x << ", " << |
| | m_end.y << ", " << |
| | m_end.z << ", " << |
| | m_mode << ", " << |
| | m_type << ", " << |
| | m_hShift << ", " << |
| | m_vShift << ", " << |
| | m_rotate << ", " << |
| | m_flip2Line << ", " << |
| | m_extendBy << ", " << |
| | m_faces.size(); |
| | if (!m_faces.empty()) { |
| | for (auto& f: m_faces) { |
| | if (!f.empty()) { |
| | ss << ", " << f ; |
| | } |
| | } |
| | } |
| |
|
| | std::string clCSV = ss.str(); |
| | std::string fmtCSV = m_format.toString(); |
| | return clCSV + ", $$$, " + fmtCSV; |
| | } |
| |
|
| | void CenterLine::dump(const char* title) |
| | { |
| | Base::Console().message("CL::dump - %s \n", title); |
| | Base::Console().message("CL::dump - %s \n", toString().c_str()); |
| | } |
| |
|
| | |
| | std::pair<Base::Vector3d, Base::Vector3d> CenterLine::rotatePointsAroundMid(const Base::Vector3d& p1, |
| | const Base::Vector3d& p2, |
| | const Base::Vector3d& mid, |
| | const double angleDeg) |
| | { |
| | std::pair<Base::Vector3d, Base::Vector3d> result; |
| | double angleRad = Base::toRadians(angleDeg); |
| |
|
| | result.first.x = ((p1.x - mid.x) * cos(angleRad)) - ((p1.y - mid.y) * sin(angleRad)) + mid.x; |
| | result.first.y = ((p1.x - mid.x) * sin(angleRad)) + ((p1.y - mid.y) * cos(angleRad)) + mid.y; |
| | result.first.z = 0.0; |
| |
|
| | result.second.x = ((p2.x - mid.x) * cos(angleRad)) - ((p2.y - mid.y) * sin(angleRad)) + mid.x; |
| | result.second.y = ((p2.x - mid.x) * sin(angleRad)) + ((p2.y - mid.y) * cos(angleRad)) + mid.y; |
| | result.second.z = 0.0; |
| |
|
| | return result; |
| | } |
| |
|
| |
|
| | |
| | std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPointsNoRef(const Base::Vector3d& start, |
| | const Base::Vector3d& end, |
| | const double scale, |
| | const double ext, |
| | const double hShift, |
| | const double vShift, |
| | const double rotate, const double viewAngleDeg) |
| | { |
| | |
| | Base::Vector3d p1 = start; |
| | Base::Vector3d p2 = end; |
| | Base::Vector3d mid = (p1 + p2) / 2.0; |
| |
|
| | |
| | Base::Vector3d clDir = p2 - p1; |
| | clDir.Normalize(); |
| | p1 = p1 - (clDir * ext); |
| | p2 = p2 + (clDir * ext); |
| |
|
| | |
| | if (!DrawUtil::fpCompare(rotate, 0.0)) { |
| | |
| | std::tie(p1, p2) = rotatePointsAroundMid(p1, p2, mid, rotate); |
| | } |
| |
|
| | |
| | if (!DrawUtil::fpCompare(hShift, 0.0)) { |
| | double hss = hShift * scale; |
| | p1.x = p1.x + hss; |
| | p2.x = p2.x + hss; |
| | } |
| | if (!DrawUtil::fpCompare(vShift, 0.0)) { |
| | double vss = vShift * scale; |
| | p1.y = p1.y + vss; |
| | p2.y = p2.y + vss; |
| | } |
| |
|
| | |
| | |
| | std::pair<Base::Vector3d, Base::Vector3d> result; |
| | result.first = p1 / scale; |
| | result.second = p2 / scale; |
| | Base::Vector3d midpoint = (result.first + result.second) / 2.0; |
| | result = rotatePointsAroundMid(result.first, result.second, midpoint, viewAngleDeg * -1.0); |
| |
|
| | return result; |
| | } |
| |
|
| | |
| | std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints(const DrawViewPart* partFeat, |
| | const std::vector<std::string>& faceNames, |
| | const CenterLine::Mode mode, |
| | const double ext, |
| | const double hShift, |
| | const double vShift, |
| | const double rotate) |
| | { |
| | |
| | if (faceNames.empty()) { |
| | Base::Console().warning("CL::calcEndPoints - no faces!\n"); |
| | return std::pair<Base::Vector3d, Base::Vector3d>(); |
| | } |
| |
|
| | Bnd_Box faceBox; |
| | faceBox.SetGap(0.0); |
| |
|
| | double scale = partFeat->getScale(); |
| |
|
| | std::vector<TopoDS_Edge> faceEdgesAll; |
| | for (auto& fn: faceNames) { |
| | if (TechDraw::DrawUtil::getGeomTypeFromName(fn) != "Face") { |
| | continue; |
| | } |
| | int idx = TechDraw::DrawUtil::getIndexFromName(fn); |
| | std::vector<TechDraw::BaseGeomPtr> faceGeoms = |
| | partFeat->getFaceEdgesByIndex(idx); |
| | if (!faceGeoms.empty()) { |
| | for (auto& fe: faceGeoms) { |
| | if (!fe->getCosmetic()) { |
| | faceEdgesAll.push_back(fe->getOCCEdge()); |
| | } |
| | } |
| | } |
| | } |
| | TopoDS_Shape faceEdgeCompound = DU::vectorToCompound(faceEdgesAll); |
| |
|
| | if (partFeat->Rotation.getValue() != 0.0) { |
| | |
| | |
| | faceEdgeCompound = ShapeUtils::rotateShape(faceEdgeCompound, |
| | partFeat->getProjectionCS(), |
| | partFeat->Rotation.getValue() * -1.0); |
| | } |
| | |
| | Base::Vector3d faceCenter = ShapeUtils::findCentroidVec(faceEdgeCompound, partFeat->getProjectionCS()); |
| | |
| | faceEdgeCompound = ShapeUtils::moveShape(faceEdgeCompound, faceCenter * -1.0); |
| |
|
| | |
| | BRepBndLib::AddOptimal(faceEdgeCompound, faceBox); |
| |
|
| | if (faceBox.IsVoid()) { |
| | Base::Console().error("CL::calcEndPoints - faceBox is void!\n"); |
| | throw Base::IndexError("CenterLine wrong number of faces."); |
| | } |
| |
|
| | double Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; |
| | faceBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); |
| |
|
| | double Xspan = fabs(Xmax - Xmin); |
| | Xspan = (Xspan / 2.0); |
| | double Xmid = 0.0; |
| | Xmax = Xmid + Xspan; |
| | Xmin = Xmid - Xspan; |
| | double Yspan = fabs(Ymax - Ymin); |
| | Yspan = (Yspan / 2.0); |
| | double Ymid = 0.0; |
| | Ymax = Ymid + Yspan; |
| | Ymin = Ymid - Yspan; |
| |
|
| | Base::Vector3d p1, p2; |
| | if (mode == Mode::VERTICAL) { |
| | p1 = Base::Vector3d(Xmid, Ymax, 0.0); |
| | p2 = Base::Vector3d(Xmid, Ymin, 0.0); |
| | } else if (mode == Mode::HORIZONTAL) { |
| | p1 = Base::Vector3d(Xmin, Ymid, 0.0); |
| | p2 = Base::Vector3d(Xmax, Ymid, 0.0); |
| | } else { |
| | Base::Console().message("CL::calcEndPoints - aligned is not applicable to Face center lines\n"); |
| | p1 = Base::Vector3d(Xmid, Ymax, 0.0); |
| | p2 = Base::Vector3d(Xmid, Ymin, 0.0); |
| | } |
| |
|
| | |
| | |
| | |
| | p1 += faceCenter; |
| | p2 += faceCenter; |
| |
|
| | Base::Vector3d mid = (p1 + p2) / 2.0; |
| |
|
| | |
| | Base::Vector3d clDir = p2 - p1; |
| | clDir.Normalize(); |
| | p1 = p1 - (clDir * ext); |
| | p2 = p2 + (clDir * ext); |
| |
|
| | |
| | if (!DrawUtil::fpCompare(rotate, 0.0)) { |
| | |
| | std::tie(p1, p2) = rotatePointsAroundMid(p1, p2, mid, rotate); |
| | } |
| |
|
| | |
| | if (!DrawUtil::fpCompare(hShift, 0.0)) { |
| | double hss = hShift * scale; |
| | p1.x = p1.x + hss; |
| | p2.x = p2.x + hss; |
| | } |
| | if (!DrawUtil::fpCompare(vShift, 0.0)) { |
| | double vss = vShift * scale; |
| | p1.y = p1.y + vss; |
| | p2.y = p2.y + vss; |
| | } |
| |
|
| | std::pair<Base::Vector3d, Base::Vector3d> result; |
| | result.first = p1 / scale; |
| | result.second = p2 / scale; |
| | return result; |
| | } |
| |
|
| | std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints2Lines(const DrawViewPart* partFeat, |
| | const std::vector<std::string>& edgeNames, |
| | const Mode mode, |
| | const double ext, |
| | const double hShift, |
| | const double vShift, |
| | const double rotate, |
| | const bool flip) |
| | |
| | { |
| | Q_UNUSED(flip) |
| |
|
| | |
| | std::pair<Base::Vector3d, Base::Vector3d> result; |
| | if (edgeNames.empty()) { |
| | Base::Console().warning("CL::calcEndPoints2Lines - no edges!\n"); |
| | return result; |
| | } |
| |
|
| | double scale = partFeat->getScale(); |
| |
|
| | std::vector<TechDraw::BaseGeomPtr> edges; |
| | for (auto& en: edgeNames) { |
| | if (TechDraw::DrawUtil::getGeomTypeFromName(en) != "Edge") { |
| | continue; |
| | } |
| | int idx = TechDraw::DrawUtil::getIndexFromName(en); |
| | TechDraw::BaseGeomPtr bg = partFeat->getGeomByIndex(idx); |
| | if (bg) { |
| | edges.push_back(bg); |
| | } else { |
| | Base::Console().message("CL::calcEndPoints2Lines - no geom for index: %d\n", idx); |
| | } |
| | } |
| | if (edges.size() != 2) { |
| | Base::Console().message("CL::calcEndPoints2Lines - wrong number of edges: %d!\n", edges.size()); |
| | throw Base::IndexError("CenterLine wrong number of edges."); |
| | } |
| |
|
| | |
| | |
| | Base::Vector3d l1p1 = DU::invertY(edges.front()->getStartPoint()); |
| | Base::Vector3d l1p2 = DU::invertY(edges.front()->getEndPoint()); |
| | Base::Vector3d l2p1 = DU::invertY(edges.back()->getStartPoint()); |
| | Base::Vector3d l2p2 = DU::invertY(edges.back()->getEndPoint()); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | if (DrawUtil::circulation(l1p1, l1p2, l2p1) != DrawUtil::circulation(l1p2, l2p2, l2p1)) { |
| | Base::Vector3d temp; |
| | temp = l1p1; |
| | l1p1 = l1p2; |
| | l1p2 = temp; |
| | } |
| |
|
| | Base::Vector3d p1 = (l1p1 + l2p1) / 2.0; |
| | Base::Vector3d p2 = (l1p2 + l2p2) / 2.0; |
| | Base::Vector3d mid = (p1 + p2) / 2.0; |
| |
|
| | |
| | |
| | |
| | bool inhibitVertical = false; |
| | bool inhibitHorizontal = false; |
| | if (DU::fpCompare(p1.y, p2.y, EWTOLERANCE)) { |
| | |
| | inhibitVertical = true; |
| | } |
| | if (DU::fpCompare(p1.x, p2.x, EWTOLERANCE)) { |
| | |
| | inhibitHorizontal = true; |
| | } |
| |
|
| | |
| | if (partFeat->Rotation.getValue() == 0.0) { |
| | |
| | if (mode == CenterLine::Mode::VERTICAL && !inhibitVertical) { |
| | p1.x = mid.x; |
| | p2.x = mid.x; |
| | } else if (mode == CenterLine::Mode::HORIZONTAL && !inhibitHorizontal) { |
| | p1.y = mid.y; |
| | p2.y = mid.y; |
| | } else if (mode == CenterLine::Mode::ALIGNED) { |
| | |
| | } |
| | } |
| |
|
| | |
| | Base::Vector3d clDir = p2 - p1; |
| | clDir.Normalize(); |
| | p1 = p1 - (clDir * ext); |
| | p2 = p2 + (clDir * ext); |
| |
|
| | |
| | if (!DrawUtil::fpCompare(rotate, 0.0)) { |
| | |
| | std::tie(p1, p2) = rotatePointsAroundMid(p1, p2, mid, rotate); |
| | } |
| |
|
| | |
| | if (!DrawUtil::fpCompare(hShift, 0.0)) { |
| | double hss = hShift * scale; |
| | p1.x = p1.x + hss; |
| | p2.x = p2.x + hss; |
| | } |
| | if (!DrawUtil::fpCompare(vShift, 0.0)) { |
| | double vss = vShift * scale; |
| | p1.y = p1.y + vss; |
| | p2.y = p2.y + vss; |
| | } |
| |
|
| | |
| | result.first = p1 / scale; |
| | result.second = p2 / scale; |
| | return result; |
| | } |
| |
|
| | std::pair<Base::Vector3d, Base::Vector3d> CenterLine::calcEndPoints2Points(const DrawViewPart* partFeat, |
| | const std::vector<std::string>& vertNames, |
| | const Mode mode, |
| | const double ext, |
| | const double hShift, |
| | const double vShift, |
| | const double rotate, |
| | const bool flip) |
| | |
| | { |
| | |
| | if (vertNames.empty()) { |
| | Base::Console().warning("CL::calcEndPoints2Points - no points!\n"); |
| | return std::pair<Base::Vector3d, Base::Vector3d>(); |
| | } |
| |
|
| | double scale = partFeat->getScale(); |
| |
|
| | std::vector<TechDraw::VertexPtr> points; |
| | for (auto& vn: vertNames) { |
| | if (TechDraw::DrawUtil::getGeomTypeFromName(vn) != "Vertex") { |
| | continue; |
| | } |
| | int idx = TechDraw::DrawUtil::getIndexFromName(vn); |
| | TechDraw::VertexPtr v = partFeat->getProjVertexByIndex(idx); |
| | if (v) { |
| | points.push_back(v); |
| | } |
| | } |
| | if (points.size() != 2) { |
| | throw Base::IndexError("CenterLine wrong number of points."); |
| | } |
| |
|
| | Base::Vector3d v1 = DU::invertY(points.front()->point()); |
| | Base::Vector3d v2 = DU::invertY(points.back()->point()); |
| | Base::Vector3d mid = (v1 + v2) / 2.0; |
| | Base::Vector3d dir = v2 - v1; |
| |
|
| | |
| | |
| | |
| |
|
| | bool inhibitVertical = false; |
| | bool inhibitHorizontal = false; |
| | if (DU::fpCompare(v1.y, v2.y, EWTOLERANCE)) { |
| | |
| | inhibitHorizontal = true; |
| | } |
| | if (DU::fpCompare(v1.x, v2.x, EWTOLERANCE)) { |
| | |
| | inhibitVertical = true; |
| | } |
| |
|
| | |
| | if (partFeat->Rotation.getValue() == 0.0) { |
| | |
| | if (mode == Mode::VERTICAL && !inhibitVertical) { |
| | |
| | v1.x = mid.x; |
| | v2.x = mid.x; |
| | } else if (mode == Mode::HORIZONTAL && !inhibitHorizontal) { |
| | |
| | v1.y = mid.y; |
| | v2.y = mid.y; |
| | } else if (mode == Mode::ALIGNED) { |
| | |
| | } |
| | } |
| |
|
| | double length = dir.Length(); |
| | dir.Normalize(); |
| | Base::Vector3d clDir(dir.y, -dir.x, dir.z); |
| |
|
| | Base::Vector3d p1 = mid + clDir * (length / 2.0); |
| | Base::Vector3d p2 = mid - clDir * (length / 2.0); |
| |
|
| | if (flip) { |
| | Base::Vector3d temp = p1; |
| | p1 = p2; |
| | p2 = temp; |
| | } |
| |
|
| | |
| | p1 = p1 + (clDir * ext); |
| | p2 = p2 - (clDir * ext); |
| |
|
| | |
| | if (!DrawUtil::fpCompare(rotate, 0.0)) { |
| | |
| | std::tie(p1, p2) = rotatePointsAroundMid(p1, p2, mid, rotate); |
| | } |
| |
|
| | |
| | if (!DrawUtil::fpCompare(hShift, 0.0)) { |
| | double hss = hShift * scale; |
| | p1.x = p1.x + hss; |
| | p2.x = p2.x + hss; |
| | } |
| | if (!DrawUtil::fpCompare(vShift, 0.0)) { |
| | double vss = vShift * scale; |
| | p1.y = p1.y + vss; |
| | p2.y = p2.y + vss; |
| | } |
| |
|
| | std::pair<Base::Vector3d, Base::Vector3d> result; |
| | result.first = p1 / scale; |
| | result.second = p2 / scale; |
| |
|
| | return result; |
| | } |
| |
|
| | |
| | unsigned int CenterLine::getMemSize () const |
| | { |
| | return 1; |
| | } |
| |
|
| | void CenterLine::Save(Base::Writer &writer) const |
| | { |
| | writer.Stream() << writer.ind() << "<Start " |
| | << "X=\"" << m_start.x << |
| | "\" Y=\"" << m_start.y << |
| | "\" Z=\"" << m_start.z << |
| | "\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<End " |
| | << "X=\"" << m_end.x << |
| | "\" Y=\"" << m_end.y << |
| | "\" Z=\"" << m_end.z << |
| | "\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<Mode value=\"" << m_mode <<"\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<HShift value=\"" << m_hShift <<"\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<VShift value=\"" << m_vShift <<"\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<Rotate value=\"" << m_rotate <<"\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<Extend value=\"" << m_extendBy <<"\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<Type value=\"" << m_type <<"\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<Flip value=\"" << m_flip2Line <<"\"/>" << std::endl; |
| | writer.Stream() |
| | << writer.ind() |
| | << "<Faces " |
| | << "FaceCount=\"" << m_faces.size() << |
| | "\">" << std::endl; |
| |
|
| | writer.incInd(); |
| | for (auto& f: m_faces) { |
| | writer.Stream() |
| | << writer.ind() |
| | << "<Face value=\"" << f <<"\"/>" << std::endl; |
| | } |
| | writer.decInd(); |
| |
|
| | writer.Stream() << writer.ind() << "</Faces>" << std::endl; |
| |
|
| | writer.Stream() |
| | << writer.ind() |
| | << "<Edges " |
| | << "EdgeCount=\"" << m_edges.size() << |
| | "\">" << std::endl; |
| |
|
| | writer.incInd(); |
| | for (auto& e: m_edges) { |
| | writer.Stream() |
| | << writer.ind() |
| | << "<Edge value=\"" << e <<"\"/>" << std::endl; |
| | } |
| | writer.decInd(); |
| | writer.Stream() << writer.ind() << "</Edges>" << std::endl; |
| |
|
| | writer.Stream() |
| | << writer.ind() |
| | << "<CLPoints " |
| | << "CLPointCount=\"" << m_verts.size() << |
| | "\">" << std::endl; |
| |
|
| | writer.incInd(); |
| | for (auto& p: m_verts) { |
| | writer.Stream() |
| | << writer.ind() |
| | << "<CLPoint value=\"" << p <<"\"/>" << std::endl; |
| | } |
| | writer.decInd(); |
| | writer.Stream() << writer.ind() << "</CLPoints>" << std::endl ; |
| |
|
| | |
| | |
| | writer.Stream() << writer.ind() << "<Style value=\"" << m_format.getStyle() << "\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<Weight value=\"" << m_format.getWidth() << "\"/>" << std::endl; |
| | writer.Stream() << writer.ind() << "<Color value=\"" << m_format.getColor().asHexString() << "\"/>" << std::endl; |
| | const char v = m_format.getVisible() ? '1' : '0'; |
| | writer.Stream() << writer.ind() << "<Visible value=\"" << v << "\"/>" << std::endl; |
| |
|
| | |
| | if (!m_geometry) { |
| | return Base::Console().error("CL::Save - m_geometry is null\n"); |
| | } |
| |
|
| | writer.Stream() << writer.ind() << "<GeometryType value=\"" << m_geometry->getGeomType() <<"\"/>" << std::endl; |
| | if (m_geometry->getGeomType() == GeomType::GENERIC) { |
| | GenericPtr gen = std::static_pointer_cast<Generic>(m_geometry); |
| | gen->Save(writer); |
| | } else if (m_geometry->getGeomType() == GeomType::CIRCLE) { |
| | TechDraw::CirclePtr circ = std::static_pointer_cast<TechDraw::Circle>(m_geometry); |
| | circ->Save(writer); |
| | } else if (m_geometry->getGeomType() == GeomType::ARCOFCIRCLE) { |
| | TechDraw::AOCPtr aoc = std::static_pointer_cast<TechDraw::AOC>(m_geometry); |
| | aoc->Save(writer); |
| | } else { |
| | Base::Console().message("CL::Save - unimplemented geomType: %d\n", static_cast<int>(m_geometry->getGeomType())); |
| | } |
| |
|
| | writer.Stream() << writer.ind() << "<LineNumber value=\"" << m_format.getLineNumber() << "\"/>" << std::endl; |
| |
|
| | } |
| |
|
| | void CenterLine::Restore(Base::XMLReader &reader) |
| | { |
| | if (!CosmeticVertex::restoreCosmetic()) { |
| | return; |
| | } |
| | |
| | |
| | reader.readElement("Start"); |
| | |
| | m_start.x = reader.getAttribute<double>("X"); |
| | m_start.y = reader.getAttribute<double>("Y"); |
| | m_start.z = reader.getAttribute<double>("Z"); |
| |
|
| | reader.readElement("End"); |
| | m_end.x = reader.getAttribute<double>("X"); |
| | m_end.y = reader.getAttribute<double>("Y"); |
| | m_end.z = reader.getAttribute<double>("Z"); |
| |
|
| | reader.readElement("Mode"); |
| | m_mode = reader.getAttribute<Mode>("value"); |
| |
|
| | reader.readElement("HShift"); |
| | m_hShift = reader.getAttribute<double>("value"); |
| | reader.readElement("VShift"); |
| | m_vShift = reader.getAttribute<double>("value"); |
| | reader.readElement("Rotate"); |
| | m_rotate = reader.getAttribute<double>("value"); |
| | reader.readElement("Extend"); |
| | m_extendBy = reader.getAttribute<double>("value"); |
| | reader.readElement("Type"); |
| | m_type = reader.getAttribute<Type>("value"); |
| | reader.readElement("Flip"); |
| | m_flip2Line = reader.getAttribute<bool>("value") == 0; |
| |
|
| | reader.readElement("Faces"); |
| | int count = reader.getAttribute<long>("FaceCount"); |
| |
|
| | int i = 0; |
| | for ( ; i < count; i++) { |
| | reader.readElement("Face"); |
| | std::string f = reader.getAttribute<const char*>("value"); |
| | m_faces.push_back(f); |
| | } |
| | reader.readEndElement("Faces"); |
| |
|
| | reader.readElement("Edges"); |
| | count = reader.getAttribute<long>("EdgeCount"); |
| |
|
| | i = 0; |
| | for ( ; i < count; i++) { |
| | reader.readElement("Edge"); |
| | std::string e = reader.getAttribute<const char*>("value"); |
| | m_edges.push_back(e); |
| | } |
| | reader.readEndElement("Edges"); |
| |
|
| | reader.readElement("CLPoints"); |
| | count = reader.getAttribute<long>("CLPointCount"); |
| |
|
| | i = 0; |
| | for ( ; i < count; i++) { |
| | reader.readElement("CLPoint"); |
| | std::string p = reader.getAttribute<const char*>("value"); |
| | m_verts.push_back(p); |
| | } |
| | reader.readEndElement("CLPoints"); |
| |
|
| | |
| | |
| | reader.readElement("Style"); |
| | m_format.setStyle(reader.getAttribute<long>("value")); |
| | reader.readElement("Weight"); |
| | m_format.setWidth(reader.getAttribute<double>("value")); |
| | reader.readElement("Color"); |
| | std::string tempHex = reader.getAttribute<const char*>("value"); |
| | Base::Color tempColor; |
| | tempColor.fromHexString(tempHex); |
| | m_format.setColor(tempColor); |
| | reader.readElement("Visible"); |
| | m_format.setVisible(reader.getAttribute<bool>("value")); |
| |
|
| | |
| | reader.readElement("GeometryType"); |
| | GeomType gType = reader.getAttribute<GeomType>("value"); |
| | if (gType == GeomType::GENERIC) { |
| | TechDraw::GenericPtr gen = std::make_shared<TechDraw::Generic> (); |
| | gen->Restore(reader); |
| | gen->setOCCEdge(GeometryUtils::edgeFromGeneric(gen)); |
| | m_geometry = gen; |
| | } else if (gType == GeomType::CIRCLE) { |
| | TechDraw::CirclePtr circ = std::make_shared<TechDraw::Circle> (); |
| | circ->Restore(reader); |
| | circ->setOCCEdge(GeometryUtils::edgeFromCircle(circ)); |
| | m_geometry = circ; |
| | } else if (gType == GeomType::ARCOFCIRCLE) { |
| | TechDraw::AOCPtr aoc = std::make_shared<TechDraw::AOC> (); |
| | aoc->Restore(reader); |
| | aoc->setOCCEdge(GeometryUtils::edgeFromCircleArc(aoc)); |
| | m_geometry = aoc; |
| | } else { |
| | Base::Console().warning("CL::Restore - unimplemented geomType: %d\n", static_cast<int>(gType)); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | if (reader.readNextElement()) { |
| | if(strcmp(reader.localName(),"LineNumber") == 0 || |
| | strcmp(reader.localName(),"ISOLineNumber") == 0 ) { |
| | |
| | m_format.setLineNumber(reader.getAttribute<long>("value")); |
| | } else { |
| | |
| | m_format.setLineNumber(LineFormat::InvalidLine); |
| | } |
| | } |
| | } |
| |
|
| | CenterLine* CenterLine::copy() const |
| | { |
| | CenterLine* newCL = new CenterLine(); |
| | newCL->m_start = m_start; |
| | newCL->m_end = m_end; |
| | newCL->m_mode = m_mode; |
| | newCL->m_hShift = m_hShift; |
| | newCL->m_vShift = m_vShift; |
| | newCL->m_rotate = m_rotate; |
| | newCL->m_extendBy = m_extendBy; |
| | newCL->m_type = m_type; |
| | newCL->m_flip2Line = m_flip2Line; |
| |
|
| | newCL->m_faces = m_faces; |
| | newCL->m_edges = m_edges; |
| | newCL->m_verts = m_verts; |
| |
|
| | TechDraw::BaseGeomPtr newGeom = m_geometry->copy(); |
| | newCL->m_geometry = newGeom; |
| |
|
| | newCL->m_format = m_format; |
| |
|
| | return newCL; |
| | } |
| |
|
| | CenterLine *CenterLine::clone() const |
| | { |
| | CenterLine* cpy = this->copy(); |
| | cpy->setTag(this->getTag()); |
| |
|
| | return cpy; |
| | } |
| |
|
| | |
| | PyObject* CenterLine::getPyObject() |
| | { |
| | if (PythonObject.is(Py::_None())) { |
| | |
| | PythonObject = Py::Object(new CenterLinePy(this), true); |
| | } |
| | return Py::new_reference_to(PythonObject); |
| | } |
| |
|
| |
|
| | void CenterLine::setShifts(const double h, const double v) |
| | { |
| | m_hShift = h; |
| | m_vShift = v; |
| | } |
| |
|
| | double CenterLine::getHShift() const |
| | { |
| | return m_hShift; |
| | } |
| |
|
| | double CenterLine::getVShift() const |
| | { |
| | return m_vShift; |
| | } |
| |
|
| | void CenterLine::setRotate(const double r) |
| | { |
| | m_rotate = r; |
| | } |
| |
|
| | double CenterLine::getRotate() const |
| | { |
| | return m_rotate; |
| | } |
| |
|
| | void CenterLine::setExtend(const double e) |
| | { |
| | m_extendBy = e; |
| | } |
| |
|
| | double CenterLine::getExtend() const |
| | { |
| | return m_extendBy; |
| | } |
| |
|
| | void CenterLine::setFlip(const bool f) |
| | { |
| | m_flip2Line = f; |
| | } |
| |
|
| | bool CenterLine::getFlip() const |
| | { |
| | return m_flip2Line; |
| | } |
| |
|
| |
|