| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #include <BRepAdaptor_Curve.hxx>
|
| | #include <CPnts_AbscissaPoint.hxx>
|
| | #include <TopoDS.hxx>
|
| | #include <TopoDS_Edge.hxx>
|
| |
|
| |
|
| | #include <Base/Sequencer.h>
|
| | #include <Mod/Part/App/PartFeature.h>
|
| | #include <Mod/Part/App/edgecluster.h>
|
| |
|
| | #include "Edge2TracObject.h"
|
| | #include "Trajectory.h"
|
| | #include "Waypoint.h"
|
| |
|
| |
|
| | using namespace Robot;
|
| | using namespace App;
|
| |
|
| | PROPERTY_SOURCE(Robot::Edge2TracObject, Robot::TrajectoryObject)
|
| |
|
| |
|
| | Edge2TracObject::Edge2TracObject()
|
| | {
|
| |
|
| | ADD_PROPERTY_TYPE(Source, (nullptr), "Edge2Trac", Prop_None, "Edges to generate the Trajectory");
|
| | ADD_PROPERTY_TYPE(SegValue, (0.5), "Edge2Trac", Prop_None, "Max deviation from original geometry");
|
| | ADD_PROPERTY_TYPE(UseRotation, (0), "Edge2Trac", Prop_None, "use orientation of the edge");
|
| | NbrOfEdges = 0;
|
| | NbrOfCluster = 0;
|
| | }
|
| |
|
| | App::DocumentObjectExecReturn* Edge2TracObject::execute()
|
| | {
|
| | App::DocumentObject* link = Source.getValue();
|
| | if (!link) {
|
| | return new App::DocumentObjectExecReturn("No object linked");
|
| | }
|
| | if (!link->isDerivedFrom<Part::Feature>()) {
|
| | return new App::DocumentObjectExecReturn("Linked object is not a Part object");
|
| | }
|
| | Part::Feature* base = static_cast<Part::Feature*>(Source.getValue());
|
| | const Part::TopoShape& TopShape = base->Shape.getShape();
|
| |
|
| | const std::vector<std::string>& SubVals = Source.getSubValuesStartsWith("Edge");
|
| | if (SubVals.empty()) {
|
| | return new App::DocumentObjectExecReturn("No Edges specified");
|
| | }
|
| |
|
| |
|
| | std::vector<TopoDS_Edge> edges;
|
| |
|
| |
|
| | for (const auto& SubVal : SubVals) {
|
| | TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(SubVal.c_str()));
|
| | edges.push_back(edge);
|
| | }
|
| |
|
| |
|
| | Part::Edgecluster acluster(edges);
|
| | Part::tEdgeClusterVector aclusteroutput = acluster.GetClusters();
|
| |
|
| | if (aclusteroutput.empty()) {
|
| | return new App::DocumentObjectExecReturn("No Edges specified");
|
| | }
|
| |
|
| |
|
| | NbrOfCluster = aclusteroutput.size();
|
| | NbrOfEdges = 0;
|
| | for (const auto& it : aclusteroutput) {
|
| | NbrOfEdges += it.size();
|
| | }
|
| |
|
| |
|
| | Robot::Trajectory trac;
|
| | bool first = true;
|
| |
|
| |
|
| | for (const auto& it : aclusteroutput) {
|
| |
|
| | for (const auto& it2 : it) {
|
| | BRepAdaptor_Curve adapt(it2);
|
| |
|
| | switch (adapt.GetType()) {
|
| | case GeomAbs_Line: {
|
| |
|
| | gp_Pnt P1 = adapt.Value(adapt.FirstParameter());
|
| | gp_Pnt P2 = adapt.Value(adapt.LastParameter());
|
| |
|
| | Base::Rotation R1;
|
| | Base::Rotation R2;
|
| |
|
| |
|
| | if (UseRotation.getValue()) {
|
| |
|
| |
|
| |
|
| | }
|
| |
|
| |
|
| | if (it2.Orientation() == TopAbs_REVERSED) {
|
| |
|
| | gp_Pnt tmpP = P1;
|
| | Base::Rotation tmpR = R1;
|
| | P1 = P2;
|
| | R1 = R2;
|
| | R2 = tmpR;
|
| | P2 = tmpP;
|
| | }
|
| | if (first) {
|
| | Waypoint wp("Pt", Base::Placement(Base::Vector3d(P1.X(), P1.Y(), P1.Z()), R1));
|
| | trac.addWaypoint(wp);
|
| | first = false;
|
| | }
|
| | Waypoint wp("Pt", Base::Placement(Base::Vector3d(P2.X(), P2.Y(), P2.Z()), R2));
|
| | trac.addWaypoint(wp);
|
| | break;
|
| | }
|
| | case GeomAbs_BSplineCurve: {
|
| | Standard_Real Length = CPnts_AbscissaPoint::Length(adapt);
|
| | Standard_Real ParLength = adapt.LastParameter() - adapt.FirstParameter();
|
| | Standard_Real NbrSegments = Round(Length / SegValue.getValue());
|
| |
|
| | Standard_Real beg = adapt.FirstParameter();
|
| | Standard_Real end = adapt.LastParameter();
|
| | Standard_Real stp = ParLength / NbrSegments;
|
| | bool reversed = false;
|
| | if (it2.Orientation() == TopAbs_REVERSED) {
|
| | std::swap(beg, end);
|
| | stp = -stp;
|
| | reversed = true;
|
| | }
|
| |
|
| | if (first) {
|
| | first = false;
|
| | }
|
| | else {
|
| | beg += stp;
|
| | }
|
| | Base::SequencerLauncher seq(
|
| | "Create waypoints",
|
| | static_cast<size_t>((end - beg) / stp)
|
| | );
|
| | if (reversed) {
|
| | for (; beg > end; beg += stp) {
|
| | gp_Pnt P = adapt.Value(beg);
|
| | Base::Rotation R1;
|
| |
|
| | if (UseRotation.getValue()) {
|
| |
|
| |
|
| | }
|
| |
|
| | Waypoint wp("Pt", Base::Placement(Base::Vector3d(P.X(), P.Y(), P.Z()), R1));
|
| | trac.addWaypoint(wp);
|
| | seq.next();
|
| | }
|
| | }
|
| | else {
|
| | for (; beg < end; beg += stp) {
|
| | gp_Pnt P = adapt.Value(beg);
|
| | Base::Rotation R1;
|
| |
|
| | if (UseRotation.getValue()) {
|
| |
|
| |
|
| | }
|
| | Waypoint wp("Pt", Base::Placement(Base::Vector3d(P.X(), P.Y(), P.Z()), R1));
|
| | trac.addWaypoint(wp);
|
| | seq.next();
|
| | }
|
| | }
|
| |
|
| | } break;
|
| | case GeomAbs_Circle: {
|
| | Standard_Real Length = CPnts_AbscissaPoint::Length(adapt);
|
| | Standard_Real ParLength = adapt.LastParameter() - adapt.FirstParameter();
|
| | Standard_Real NbrSegments = Round(Length / SegValue.getValue());
|
| | Standard_Real SegLength = ParLength / NbrSegments;
|
| |
|
| | if (it2.Orientation() == TopAbs_REVERSED) {
|
| |
|
| | double i = adapt.LastParameter();
|
| | if (first) {
|
| | first = false;
|
| | }
|
| | else {
|
| | i -= SegLength;
|
| | }
|
| | for (; i > adapt.FirstParameter(); i -= SegLength) {
|
| | gp_Pnt P = adapt.Value(i);
|
| | Base::Rotation R1;
|
| |
|
| | if (UseRotation.getValue()) {
|
| |
|
| |
|
| | }
|
| | Waypoint wp("Pt", Base::Placement(Base::Vector3d(P.X(), P.Y(), P.Z()), R1));
|
| | trac.addWaypoint(wp);
|
| | }
|
| | }
|
| | else {
|
| | double i = adapt.FirstParameter();
|
| | if (first) {
|
| | first = false;
|
| | }
|
| | else {
|
| | i += SegLength;
|
| | }
|
| | for (; i < adapt.LastParameter(); i += SegLength) {
|
| | gp_Pnt P = adapt.Value(i);
|
| | Base::Rotation R1;
|
| |
|
| | if (UseRotation.getValue()) {
|
| |
|
| |
|
| | }
|
| | Waypoint wp("Pt", Base::Placement(Base::Vector3d(P.X(), P.Y(), P.Z()), R1));
|
| | trac.addWaypoint(wp);
|
| | }
|
| | }
|
| | break;
|
| | }
|
| |
|
| | default:
|
| | throw Base::TypeError("Unknown Edge type in Robot::Edge2TracObject::execute()");
|
| | }
|
| | }
|
| | }
|
| |
|
| | Trajectory.setValue(trac);
|
| |
|
| | return App::DocumentObject::StdReturn;
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | void Edge2TracObject::onChanged(const Property* prop)
|
| | {
|
| | App::GeoFeature::onChanged(prop);
|
| | }
|
| |
|