Sketcher: Intersection externals
This commit is contained in:
committed by
WandererFan
parent
f3c79302c4
commit
0e5e071d72
@@ -141,6 +141,11 @@ SketchObject::SketchObject()
|
||||
"Sketch",
|
||||
(App::PropertyType)(App::Prop_None | App::Prop_ReadOnly),
|
||||
"Sketch external geometry");
|
||||
ADD_PROPERTY_TYPE(ExternalTypes,
|
||||
({}),
|
||||
"Sketch",
|
||||
(App::PropertyType)(App::Prop_None | App::Prop_Hidden),
|
||||
"Sketch external geometry type: 0 = projection, 1 = intersection, 2 = both.");
|
||||
ADD_PROPERTY_TYPE(FullyConstrained,
|
||||
(false),
|
||||
"Sketch",
|
||||
@@ -7721,8 +7726,12 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName, boo
|
||||
}
|
||||
|
||||
// get the actual lists of the externals
|
||||
std::vector<long> Types = ExternalTypes.getValues();
|
||||
std::vector<DocumentObject*> Objects = ExternalGeometry.getValues();
|
||||
std::vector<std::string> SubElements = ExternalGeometry.getSubValues();
|
||||
if (Types.size() != Objects.size()) {
|
||||
Types.resize(Objects.size(), 0);
|
||||
}
|
||||
|
||||
const std::vector<DocumentObject*> originalObjects = Objects;
|
||||
const std::vector<std::string> originalSubElements = SubElements;
|
||||
@@ -7734,21 +7743,35 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName, boo
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool add = true;
|
||||
for (size_t i = 0; i < Objects.size(); ++i) {
|
||||
if (Objects[i] == Obj && std::string(SubName) == SubElements[i]) {
|
||||
Base::Console().Error("Link to %s already exists in this sketch.\n", SubName);
|
||||
return -1;
|
||||
if (Types[i] == (int)ExtType::Both
|
||||
|| (Types[i] == (int)ExtType::Projection && !intersection)
|
||||
|| (Types[i] == (int)ExtType::Intersection && intersection)) {
|
||||
Base::Console().Error("Link to %s already exists in this sketch.\n", SubName);
|
||||
return -1;
|
||||
}
|
||||
// Case where projections are already there when adding intersections.
|
||||
add = false;
|
||||
Types[i] = (int)ExtType::Both;
|
||||
}
|
||||
}
|
||||
if (add) {
|
||||
// add the new ones
|
||||
Objects.push_back(Obj);
|
||||
SubElements.emplace_back(SubName);
|
||||
Types.push_back((int)(intersection ? ExtType::Intersection : ExtType::Projection));
|
||||
if (intersection) {}
|
||||
|
||||
// add the new ones
|
||||
Objects.push_back(Obj);
|
||||
SubElements.emplace_back(SubName);
|
||||
// set the Link list.
|
||||
ExternalGeometry.setValues(Objects, SubElements);
|
||||
}
|
||||
ExternalTypes.setValues(Types);
|
||||
|
||||
// set the Link list.
|
||||
ExternalGeometry.setValues(Objects, SubElements);
|
||||
try {
|
||||
rebuildExternalGeometry(defining, intersection);
|
||||
ExternalToAdd ext{ Obj, std::string(SubName), defining, intersection };
|
||||
rebuildExternalGeometry(ext);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
@@ -8731,6 +8754,8 @@ void processEdge(const TopoDS_Edge& edge,
|
||||
}
|
||||
else if (curve.GetType() == GeomAbs_Ellipse) {
|
||||
|
||||
gp_Pnt P1 = curve.Value(curve.FirstParameter());
|
||||
gp_Pnt P2 = curve.Value(curve.LastParameter());
|
||||
gp_Elips elipsOrig = curve.Ellipse();
|
||||
gp_Elips elipsDest;
|
||||
gp_Pnt origCenter = elipsOrig.Location();
|
||||
@@ -8792,11 +8817,22 @@ void processEdge(const TopoDS_Edge& edge,
|
||||
|
||||
// projection is a circle
|
||||
if ((RDest - rDest) < (double)Precision::Confusion()) {
|
||||
Handle(Geom_Circle) curve = new Geom_Circle(destCurveAx2, 0.5 * (rDest + RDest));
|
||||
auto* circle = new Part::GeomCircle();
|
||||
circle->setHandle(curve);
|
||||
GeometryFacade::setConstruction(circle, true);
|
||||
geos.emplace_back(circle);
|
||||
Handle(Geom_Circle) curve2 = new Geom_Circle(destCurveAx2, 0.5 * (rDest + RDest));
|
||||
if (P1.SquareDistance(P2) < Precision::Confusion()) {
|
||||
auto* circle = new Part::GeomCircle();
|
||||
circle->setHandle(curve2);
|
||||
GeometryFacade::setConstruction(circle, true);
|
||||
geos.emplace_back(circle);
|
||||
}
|
||||
else {
|
||||
auto* arc = new Part::GeomArcOfCircle();
|
||||
Handle(Geom_TrimmedCurve) tCurve = new Geom_TrimmedCurve(curve2,
|
||||
curve.FirstParameter(),
|
||||
curve.LastParameter());
|
||||
arc->setHandle(tCurve);
|
||||
GeometryFacade::setConstruction(arc, true);
|
||||
geos.emplace_back(arc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (sketchPlane.Position().Direction().IsNormal(
|
||||
@@ -8818,11 +8854,23 @@ void processEdge(const TopoDS_Edge& edge,
|
||||
elipsDest.SetMinorRadius(destAxisMinor.Magnitude());
|
||||
|
||||
|
||||
Handle(Geom_Ellipse) curve = new Geom_Ellipse(elipsDest);
|
||||
auto* ellipse = new Part::GeomEllipse();
|
||||
ellipse->setHandle(curve);
|
||||
GeometryFacade::setConstruction(ellipse, true);
|
||||
geos.emplace_back(ellipse);
|
||||
if (P1.SquareDistance(P2) < Precision::Confusion()) {
|
||||
Handle(Geom_Ellipse) curve = new Geom_Ellipse(elipsDest);
|
||||
auto* ellipse = new Part::GeomEllipse();
|
||||
ellipse->setHandle(curve);
|
||||
GeometryFacade::setConstruction(ellipse, true);
|
||||
geos.emplace_back(ellipse);
|
||||
}
|
||||
else {
|
||||
auto* aoe = new Part::GeomArcOfEllipse();
|
||||
Handle(Geom_Curve) curve2 = new Geom_Ellipse(elipsDest);
|
||||
Handle(Geom_TrimmedCurve) tCurve = new Geom_TrimmedCurve(curve2,
|
||||
curve.FirstParameter(),
|
||||
curve.LastParameter());
|
||||
aoe->setHandle(tCurve);
|
||||
GeometryFacade::setConstruction(aoe, true);
|
||||
geos.emplace_back(aoe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8929,15 +8977,19 @@ std::vector<TopoDS_Shape> projectShape(const TopoDS_Shape& inShape, const gp_Ax3
|
||||
}
|
||||
}
|
||||
|
||||
void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
void SketchObject::rebuildExternalGeometry(std::optional<ExternalToAdd> extToAdd)
|
||||
{
|
||||
Base::StateLocker lock(managedoperation, true); // no need to check input data validity as this is an sketchobject managed operation.
|
||||
|
||||
// get the actual lists of the externals
|
||||
auto Types = ExternalTypes.getValues();
|
||||
auto Objects = ExternalGeometry.getValues();
|
||||
auto SubElements = ExternalGeometry.getSubValues();
|
||||
assert(externalGeoRef.size() == Objects.size());
|
||||
auto keys = externalGeoRef;
|
||||
if (Types.size() != Objects.size()) {
|
||||
Types.resize(Objects.size(), 0);
|
||||
}
|
||||
|
||||
// re-check for any missing geometry element. The code here has a side
|
||||
// effect that the linked external geometry will continue to work even if
|
||||
@@ -9007,169 +9059,211 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
const std::string &SubElement=SubElements[i];
|
||||
const std::string &key = keys[i];
|
||||
|
||||
bool beingCreated = false;
|
||||
if (extToAdd) {
|
||||
beingCreated = extToAdd->obj == Obj && extToAdd->subname == SubElement;
|
||||
}
|
||||
|
||||
bool projection = Types[i] == (int)ExtType::Projection || Types[i] == (int)ExtType::Both;
|
||||
bool intersection = Types[i] == (int)ExtType::Intersection || Types[i] == (int)ExtType::Both;
|
||||
|
||||
// Skip frozen geometries
|
||||
bool frozen = false;
|
||||
bool sync = false;
|
||||
bool intersection = addIntersection && (i+1 == (int)Objects.size());
|
||||
for(auto id : externalGeoRefMap[key]) {
|
||||
auto it = externalGeoMap.find(id);
|
||||
if(it != externalGeoMap.end()) {
|
||||
auto egf = ExternalGeometryFacade::getFacade(ExternalGeo[it->second]);
|
||||
if(egf->testFlag(ExternalGeometryExtension::Frozen))
|
||||
if(egf->testFlag(ExternalGeometryExtension::Frozen)) {
|
||||
frozen = true;
|
||||
if(egf->testFlag(ExternalGeometryExtension::Sync))
|
||||
}
|
||||
if (egf->testFlag(ExternalGeometryExtension::Sync)) {
|
||||
sync = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(frozen && !sync) {
|
||||
refSet.insert(std::move(key));
|
||||
continue;
|
||||
}
|
||||
if(!Obj || !Obj->getNameInDocument())
|
||||
if (!Obj || !Obj->getNameInDocument()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Part::Geometry> > geos;
|
||||
|
||||
try {
|
||||
TopoDS_Shape refSubShape;
|
||||
auto importVertex = [&](const TopoDS_Shape& refSubShape) {
|
||||
gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(refSubShape));
|
||||
GeomAPI_ProjectPointOnSurf proj(P, gPlane);
|
||||
P = proj.NearestPoint();
|
||||
Base::Vector3d p(P.X(), P.Y(), P.Z());
|
||||
invPlm.multVec(p, p);
|
||||
|
||||
if (Obj->isDerivedFrom<Part::Datum>()) {
|
||||
auto* datum = static_cast<const Part::Datum*>(Obj);
|
||||
refSubShape = datum->getShape();
|
||||
}
|
||||
else if (Obj->isDerivedFrom<Part::Feature>()) {
|
||||
try {
|
||||
Part::GeomPoint* point = new Part::GeomPoint(p);
|
||||
GeometryFacade::setConstruction(point, true);
|
||||
geos.emplace_back(point);
|
||||
};
|
||||
|
||||
try {
|
||||
TopoDS_Shape refSubShape;
|
||||
|
||||
if (Obj->isDerivedFrom<Part::Datum>()) {
|
||||
auto* datum = static_cast<const Part::Datum*>(Obj);
|
||||
refSubShape = datum->getShape();
|
||||
}
|
||||
else if (Obj->isDerivedFrom<Part::Feature>()) {
|
||||
auto* refObj = static_cast<const Part::Feature*>(Obj);
|
||||
const Part::TopoShape& refShape = refObj->Shape.getShape();
|
||||
refSubShape = refShape.getSubShape(SubElement.c_str());
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
throw Base::CADKernelError(e.GetMessageString());
|
||||
else if (Obj->isDerivedFrom<App::Plane>()) {
|
||||
auto* pl = static_cast<const App::Plane*>(Obj);
|
||||
Base::Placement plm = pl->Placement.getValue();
|
||||
Base::Vector3d base = plm.getPosition();
|
||||
Base::Rotation rot = plm.getRotation();
|
||||
Base::Vector3d normal(0, 0, 1);
|
||||
rot.multVec(normal, normal);
|
||||
gp_Pln plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z));
|
||||
BRepBuilderAPI_MakeFace fBuilder(plane);
|
||||
if (!fBuilder.IsDone())
|
||||
throw Base::RuntimeError(
|
||||
"Sketcher: addExternal(): Failed to build face from App::Plane");
|
||||
|
||||
TopoDS_Face f = TopoDS::Face(fBuilder.Shape());
|
||||
refSubShape = f;
|
||||
}
|
||||
else {
|
||||
throw Base::TypeError(
|
||||
"Datum feature type is not yet supported as external geometry for a sketch");
|
||||
}
|
||||
}
|
||||
else if (Obj->isDerivedFrom<App::Plane>()) {
|
||||
auto* pl = static_cast<const App::Plane*>(Obj);
|
||||
Base::Placement plm = pl->Placement.getValue();
|
||||
Base::Vector3d base = plm.getPosition();
|
||||
Base::Rotation rot = plm.getRotation();
|
||||
Base::Vector3d normal(0, 0, 1);
|
||||
rot.multVec(normal, normal);
|
||||
gp_Pln plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z));
|
||||
BRepBuilderAPI_MakeFace fBuilder(plane);
|
||||
if (!fBuilder.IsDone())
|
||||
throw Base::RuntimeError(
|
||||
"Sketcher: addExternal(): Failed to build face from App::Plane");
|
||||
|
||||
TopoDS_Face f = TopoDS::Face(fBuilder.Shape());
|
||||
refSubShape = f;
|
||||
}
|
||||
else {
|
||||
throw Base::TypeError(
|
||||
"Datum feature type is not yet supported as external geometry for a sketch");
|
||||
}
|
||||
if (projection) {
|
||||
switch (refSubShape.ShapeType()) {
|
||||
case TopAbs_FACE: {
|
||||
const TopoDS_Face& face = TopoDS::Face(refSubShape);
|
||||
BRepAdaptor_Surface surface(face);
|
||||
if (surface.GetType() == GeomAbs_Plane) {
|
||||
// Check that the plane is perpendicular to the sketch plane
|
||||
Geom_Plane plane = surface.Plane();
|
||||
gp_Dir dnormal = plane.Axis().Direction();
|
||||
gp_Dir snormal = sketchPlane.Axis().Direction();
|
||||
|
||||
switch (refSubShape.ShapeType()) {
|
||||
case TopAbs_FACE: {
|
||||
const TopoDS_Face& face = TopoDS::Face(refSubShape);
|
||||
BRepAdaptor_Surface surface(face);
|
||||
if (surface.GetType() == GeomAbs_Plane) {
|
||||
// Check that the plane is perpendicular to the sketch plane
|
||||
Geom_Plane plane = surface.Plane();
|
||||
gp_Dir dnormal = plane.Axis().Direction();
|
||||
gp_Dir snormal = sketchPlane.Axis().Direction();
|
||||
// Extract all edges from the face
|
||||
TopExp_Explorer edgeExp;
|
||||
for (edgeExp.Init(face, TopAbs_EDGE); edgeExp.More(); edgeExp.Next()) {
|
||||
TopoDS_Edge edge = TopoDS::Edge(edgeExp.Current());
|
||||
// Process each edge
|
||||
processEdge(edge, geos, gPlane, invPlm, mov, sketchPlane, invRot, sketchAx3, aProjFace);
|
||||
}
|
||||
|
||||
// Extract all edges from the face
|
||||
TopExp_Explorer edgeExp;
|
||||
for (edgeExp.Init(face, TopAbs_EDGE); edgeExp.More(); edgeExp.Next()) {
|
||||
TopoDS_Edge edge = TopoDS::Edge(edgeExp.Current());
|
||||
// Process each edge
|
||||
processEdge(edge, geos, gPlane, invPlm, mov, sketchPlane, invRot, sketchAx3, aProjFace);
|
||||
}
|
||||
|
||||
if (fabs(dnormal.Angle(snormal) - M_PI_2) < Precision::Confusion()) {
|
||||
// The face is normal to the sketch plane
|
||||
// We don't want to keep the projection of all the edges of the face.
|
||||
// We need a single line that goes from min to max of all the projections.
|
||||
bool initialized = false;
|
||||
Base::Vector3d start, end;
|
||||
// Lambda to determine if a point should replace start or end
|
||||
auto updateExtremes = [&](const Base::Vector3d& point) {
|
||||
if ((point - start).Length() < (point - end).Length()) {
|
||||
// `point` is closer to `start` than `end`, check if it's further out than `start`
|
||||
if ((point - end).Length() > (end - start).Length()) {
|
||||
start = point;
|
||||
if (fabs(dnormal.Angle(snormal) - M_PI_2) < Precision::Confusion()) {
|
||||
// The face is normal to the sketch plane
|
||||
// We don't want to keep the projection of all the edges of the face.
|
||||
// We need a single line that goes from min to max of all the projections.
|
||||
bool initialized = false;
|
||||
Base::Vector3d start, end;
|
||||
// Lambda to determine if a point should replace start or end
|
||||
auto updateExtremes = [&](const Base::Vector3d& point) {
|
||||
if ((point - start).Length() < (point - end).Length()) {
|
||||
// `point` is closer to `start` than `end`, check if it's further out than `start`
|
||||
if ((point - end).Length() > (end - start).Length()) {
|
||||
start = point;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// `point` is closer to `end`, check if it's further out than `end`
|
||||
if ((point - start).Length() > (end - start).Length()) {
|
||||
end = point;
|
||||
}
|
||||
}
|
||||
};
|
||||
for (auto& geo : geos) {
|
||||
auto* line = dynamic_cast<Part::GeomLineSegment*>(geo.get());
|
||||
if (!line) {
|
||||
// The face being normal to the sketch, we should have
|
||||
// only lines. This is just a fail-safe in case there's a
|
||||
// straight bspline or something like this.
|
||||
continue;
|
||||
}
|
||||
if (!initialized) {
|
||||
start = line->getStartPoint();
|
||||
end = line->getEndPoint();
|
||||
initialized = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
updateExtremes(line->getStartPoint());
|
||||
updateExtremes(line->getEndPoint());
|
||||
}
|
||||
if (initialized) {
|
||||
auto* unifiedLine = new Part::GeomLineSegment();
|
||||
unifiedLine->setPoints(start, end);
|
||||
geos.clear(); // Clear other segments
|
||||
geos.emplace_back(unifiedLine);
|
||||
}
|
||||
else {
|
||||
// `point` is closer to `end`, check if it's further out than `end`
|
||||
if ((point - start).Length() > (end - start).Length()) {
|
||||
end = point;
|
||||
// In case we have not initialized, perhaps the projections were
|
||||
// only straight bsplines.
|
||||
// Then we use the old method that will give a line with 20000 length:
|
||||
// Get vector that is normal to both sketch plane normal and plane normal.
|
||||
// This is the line's direction
|
||||
gp_Dir lnormal = dnormal.Crossed(snormal);
|
||||
BRepBuilderAPI_MakeEdge builder(gp_Lin(plane.Location(), lnormal));
|
||||
builder.Build();
|
||||
if (builder.IsDone()) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(builder.Shape());
|
||||
BRepAdaptor_Curve curve(edge);
|
||||
if (curve.GetType() == GeomAbs_Line) {
|
||||
geos.emplace_back(projectLine(curve, gPlane, invPlm));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
for (auto& geo : geos) {
|
||||
auto* line = dynamic_cast<Part::GeomLineSegment*>(geo.get());
|
||||
if (!line) {
|
||||
continue; // we should have only lines
|
||||
}
|
||||
if (!initialized) {
|
||||
start = line->getStartPoint();
|
||||
end = line->getEndPoint();
|
||||
initialized = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
updateExtremes(line->getStartPoint());
|
||||
updateExtremes(line->getEndPoint());
|
||||
}
|
||||
|
||||
auto* unifiedLine = new Part::GeomLineSegment();
|
||||
unifiedLine->setPoints(start, end);
|
||||
geos.clear(); // Clear other segments
|
||||
geos.emplace_back(unifiedLine);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::vector<TopoDS_Shape> res = projectShape(face, sketchAx3);
|
||||
for (auto& resShape : res) {
|
||||
TopExp_Explorer explorer(resShape, TopAbs_EDGE);
|
||||
while (explorer.More()) {
|
||||
TopoDS_Edge projEdge = TopoDS::Edge(explorer.Current());
|
||||
processEdge2(projEdge, geos);
|
||||
explorer.Next();
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::vector<TopoDS_Shape> res = projectShape(face, sketchAx3);
|
||||
for (auto& resShape : res) {
|
||||
TopExp_Explorer explorer(resShape, TopAbs_EDGE);
|
||||
while (explorer.More()) {
|
||||
TopoDS_Edge projEdge = TopoDS::Edge(explorer.Current());
|
||||
processEdge2(projEdge, geos);
|
||||
explorer.Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case TopAbs_EDGE: {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(refSubShape);
|
||||
processEdge(edge, geos, gPlane, invPlm, mov, sketchPlane, invRot, sketchAx3, aProjFace);
|
||||
} break;
|
||||
case TopAbs_VERTEX: {
|
||||
importVertex(refSubShape);
|
||||
} break;
|
||||
default:
|
||||
throw Base::TypeError("Unknown type of geometry");
|
||||
break;
|
||||
}
|
||||
if (beingCreated && !extToAdd->intersection) {
|
||||
// We are adding the projections, so we need to initialize those
|
||||
for (auto& geo : geos) {
|
||||
auto egf = ExternalGeometryFacade::getFacade(geo.get());
|
||||
egf->setFlag(ExternalGeometryExtension::Defining, extToAdd->defining);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case TopAbs_EDGE: {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(refSubShape);
|
||||
processEdge(edge, geos, gPlane, invPlm, mov, sketchPlane, invRot, sketchAx3, aProjFace);
|
||||
} break;
|
||||
case TopAbs_VERTEX: {
|
||||
gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(refSubShape));
|
||||
GeomAPI_ProjectPointOnSurf proj(P, gPlane);
|
||||
P = proj.NearestPoint();
|
||||
Base::Vector3d p(P.X(), P.Y(), P.Z());
|
||||
invPlm.multVec(p, p);
|
||||
|
||||
auto* point = new Part::GeomPoint(p);
|
||||
GeometryFacade::setConstruction(point, true);
|
||||
geos.emplace_back(point);
|
||||
} break;
|
||||
default:
|
||||
throw Base::TypeError("Unknown type of geometry");
|
||||
break;
|
||||
}
|
||||
int projSize = geos.size();
|
||||
|
||||
if (intersection && (refSubShape.ShapeType() == TopAbs_EDGE
|
||||
|| refSubShape.ShapeType() == TopAbs_FACE))
|
||||
{
|
||||
if (intersection) {
|
||||
FCBRepAlgoAPI_Section maker(refSubShape, sketchPlane);
|
||||
maker.Approximation(Standard_True);
|
||||
if (!maker.IsDone())
|
||||
FC_THROWM(Base::CADKernelError,"Failed to get intersection");
|
||||
FC_THROWM(Base::CADKernelError, "Failed to get intersection");
|
||||
Part::TopoShape intersectionShape(maker.Shape());
|
||||
auto edges = intersectionShape.getSubTopoShapes(TopAbs_EDGE);
|
||||
for (const auto& s : edges) {
|
||||
TopoDS_Edge edge = TopoDS::Edge(s.getShape());
|
||||
processEdge(edge, geos, gPlane, invPlm, mov, sketchPlane, invRot, sketchAx3, aProjFace);
|
||||
}
|
||||
// Section of some face (e.g. sphere) produce more than one arcs
|
||||
// from the same circle. So we try to fit the arcs with a single
|
||||
// circle/arc.
|
||||
@@ -9190,6 +9284,17 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto& s : intersectionShape.getSubShapes(TopAbs_VERTEX, TopAbs_EDGE)) {
|
||||
importVertex(s);
|
||||
}
|
||||
|
||||
if (beingCreated && extToAdd->intersection) {
|
||||
// We are adding the projections, so we need to initialize those
|
||||
for (size_t i = projSize; i < geos.size(); ++i) {
|
||||
auto egf = ExternalGeometryFacade::getFacade(geos[i].get());
|
||||
egf->setFlag(ExternalGeometryExtension::Defining, extToAdd->defining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Base::Exception &e) {
|
||||
@@ -9209,25 +9314,18 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
<< getFullName() << ": " << key << std::endl << "Unknown exception");
|
||||
continue;
|
||||
}
|
||||
if(geos.empty())
|
||||
if (geos.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!refSet.emplace(key).second) {
|
||||
FC_WARN("Duplicated external reference in " << getFullName() << ": " << key);
|
||||
continue;
|
||||
}
|
||||
if (intersection) {
|
||||
for(auto &geo : geos) {
|
||||
auto egf = ExternalGeometryFacade::getFacade(geo.get());
|
||||
egf->setFlag(ExternalGeometryExtension::Defining, defining);
|
||||
}
|
||||
} else if (defining && i+1==(int)Objects.size()) {
|
||||
for(auto &geo : geos)
|
||||
ExternalGeometryFacade::getFacade(geo.get())->setFlag(
|
||||
ExternalGeometryExtension::Defining);
|
||||
}
|
||||
for(auto &geo : geos)
|
||||
|
||||
for (auto& geo : geos) {
|
||||
ExternalGeometryFacade::getFacade(geo.get())->setRef(key);
|
||||
}
|
||||
newGeos.push_back(std::move(geos));
|
||||
}
|
||||
|
||||
@@ -9308,8 +9406,9 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
solverNeedsUpdate=true;
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
|
||||
if(hasError && this->isRecomputing())
|
||||
if (hasError && this->isRecomputing()) {
|
||||
throw Base::RuntimeError("Missing external geometry reference");
|
||||
}
|
||||
}
|
||||
|
||||
void SketchObject::fixExternalGeometry(const std::vector<int> &geoIds) {
|
||||
|
||||
@@ -46,6 +46,20 @@ namespace Sketcher
|
||||
|
||||
class SketchAnalysis;
|
||||
|
||||
struct ExternalToAdd
|
||||
{
|
||||
App::DocumentObject* obj;
|
||||
std::string subname;
|
||||
bool defining;
|
||||
bool intersection;
|
||||
};
|
||||
enum class ExtType
|
||||
{
|
||||
Projection,
|
||||
Intersection,
|
||||
Both
|
||||
};
|
||||
|
||||
class SketcherExport SketchObject: public Part::Part2DObject
|
||||
{
|
||||
typedef Part::Part2DObject inherited;
|
||||
@@ -68,6 +82,7 @@ public:
|
||||
Part ::PropertyGeometryList Geometry;
|
||||
Sketcher::PropertyConstraintList Constraints;
|
||||
App ::PropertyLinkSubList ExternalGeometry;
|
||||
App::PropertyIntegerList ExternalTypes;
|
||||
App ::PropertyLinkListHidden Exports;
|
||||
Part ::PropertyGeometryList ExternalGeo;
|
||||
App ::PropertyBool FullyConstrained;
|
||||
@@ -231,7 +246,9 @@ public:
|
||||
return ExternalGeo.getValues();
|
||||
}
|
||||
/// rebuilds external geometry (projection onto the sketch plane)
|
||||
void rebuildExternalGeometry(bool defining = false, bool intersection = false);
|
||||
// It uses std::optional because this function is actually used to both recompute external
|
||||
// geometries but also to add new external geometries. Ideally this should be refactored.
|
||||
void rebuildExternalGeometry(std::optional<ExternalToAdd> extToAdd = std::nullopt);
|
||||
/// returns the number of external Geometry entities
|
||||
int getExternalGeometryCount() const
|
||||
{
|
||||
|
||||
@@ -253,12 +253,14 @@ carbonCopy(objName:str, asConstruction=True)
|
||||
<UserDocu>
|
||||
Add a link to an external geometry.
|
||||
|
||||
addExternal(objName:str, subName:str)
|
||||
addExternal(objName:str, subName:str, bool:defining, bool:intersection)
|
||||
|
||||
Args:
|
||||
objName: The name of the document object to reference.
|
||||
subName: The name of the sub-element of the object's shape to link as
|
||||
"external geometry".
|
||||
defining: Should the external edges be defining or construction?
|
||||
intersection: Should the external edges be projections or intersections?
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
|
||||
@@ -557,19 +557,35 @@ PyObject* SketchObjectPy::addExternal(PyObject* args)
|
||||
{
|
||||
char* ObjectName;
|
||||
char* SubName;
|
||||
PyObject* defining; // this is an optional argument default false
|
||||
PyObject* defining; // this is an optional argument default false
|
||||
PyObject* intersection; // this is an optional argument default false
|
||||
bool isDefining;
|
||||
if (!PyArg_ParseTuple(args, "ssO!", &ObjectName, &SubName, &PyBool_Type, &defining)) {
|
||||
PyErr_Clear();
|
||||
if (!PyArg_ParseTuple(args, "ss", &ObjectName, &SubName)) {
|
||||
return nullptr;
|
||||
bool isIntersection;
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"ssO!O!",
|
||||
&ObjectName,
|
||||
&SubName,
|
||||
&PyBool_Type,
|
||||
&defining,
|
||||
&PyBool_Type,
|
||||
&intersection)) {
|
||||
if (!PyArg_ParseTuple(args, "ssO!", &ObjectName, &SubName, &PyBool_Type, &defining)) {
|
||||
PyErr_Clear();
|
||||
if (!PyArg_ParseTuple(args, "ss", &ObjectName, &SubName)) {
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
isDefining = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
isDefining = false;
|
||||
isDefining = Base::asBoolean(defining);
|
||||
}
|
||||
isIntersection = false;
|
||||
}
|
||||
else {
|
||||
isDefining = Base::asBoolean(defining);
|
||||
isIntersection = Base::asBoolean(intersection);
|
||||
}
|
||||
|
||||
// get the target object for the external link
|
||||
@@ -590,7 +606,7 @@ PyObject* SketchObjectPy::addExternal(PyObject* args)
|
||||
}
|
||||
|
||||
// add the external
|
||||
if (skObj->addExternal(Obj, SubName, isDefining) < 0) {
|
||||
if (skObj->addExternal(Obj, SubName, isDefining, isIntersection) < 0) {
|
||||
std::stringstream str;
|
||||
str << "Not able to add external shape element " << SubName;
|
||||
PyErr_SetString(PyExc_ValueError, str.str().c_str());
|
||||
|
||||
@@ -115,7 +115,9 @@ CmdSketcherToggleConstruction::CmdSketcherToggleConstruction()
|
||||
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_CreatePeriodicBSplineByInterpolation");
|
||||
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_CompCreateBSpline");
|
||||
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_CarbonCopy");
|
||||
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_CompExternal");
|
||||
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_External");
|
||||
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_Intersection");
|
||||
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_ToggleConstruction");
|
||||
}
|
||||
|
||||
|
||||
@@ -1434,7 +1434,63 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================================
|
||||
// Group for external tools =============================================
|
||||
|
||||
class CmdSketcherCompExternal: public Gui::GroupCommand
|
||||
{
|
||||
public:
|
||||
CmdSketcherCompExternal()
|
||||
: GroupCommand("Sketcher_CompExternal")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("Create external");
|
||||
sToolTipText = QT_TR_NOOP("Create external edges linked to external geometries.");
|
||||
sWhatsThis = "Sketcher_CompExternal";
|
||||
sStatusTip = sToolTipText;
|
||||
eType = ForEdit;
|
||||
|
||||
setCheckable(false);
|
||||
|
||||
addCommand("Sketcher_External");
|
||||
addCommand("Sketcher_Intersection");
|
||||
}
|
||||
|
||||
void updateAction(int mode) override
|
||||
{
|
||||
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(getAction());
|
||||
if (!pcAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QAction*> al = pcAction->actions();
|
||||
int index = pcAction->property("defaultAction").toInt();
|
||||
switch (static_cast<GeometryCreationMode>(mode)) {
|
||||
case GeometryCreationMode::Normal:
|
||||
al[0]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_External"));
|
||||
al[1]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_Intersection"));
|
||||
getAction()->setIcon(al[index]->icon());
|
||||
break;
|
||||
case GeometryCreationMode::Construction:
|
||||
al[0]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_External_Constr"));
|
||||
al[1]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_Intersection_Constr"));
|
||||
getAction()->setIcon(al[index]->icon());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char* className() const override
|
||||
{
|
||||
return "CmdSketcherCompExternal";
|
||||
}
|
||||
|
||||
bool isActive() override
|
||||
{
|
||||
return isCommandActive(getActiveGuiDocument());
|
||||
}
|
||||
};
|
||||
|
||||
// Externals - Projection ==================================================================
|
||||
|
||||
DEF_STD_CMD_AU(CmdSketcherExternal)
|
||||
|
||||
@@ -1443,8 +1499,10 @@ CmdSketcherExternal::CmdSketcherExternal()
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("Create external geometry");
|
||||
sToolTipText = QT_TR_NOOP("Create an edge linked to an external geometry");
|
||||
sMenuText = QT_TR_NOOP("Create external projection geometry");
|
||||
sToolTipText = QT_TR_NOOP("Create the projection edges of an external geometry.\n"
|
||||
"External edges can be either defining or construction geometries.\n"
|
||||
"You can use the toggle construction tool.");
|
||||
sWhatsThis = "Sketcher_External";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_External";
|
||||
@@ -1465,6 +1523,39 @@ bool CmdSketcherExternal::isActive()
|
||||
return isCommandActive(getActiveGuiDocument());
|
||||
}
|
||||
|
||||
// Externals - Intersection ==================================================================
|
||||
|
||||
DEF_STD_CMD_AU(CmdSketcherIntersection)
|
||||
|
||||
CmdSketcherIntersection::CmdSketcherIntersection()
|
||||
: Command("Sketcher_Intersection")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("Create external intersection geometry");
|
||||
sToolTipText =
|
||||
QT_TR_NOOP("Create the intersection edges of an external geometry with the sketch plane.\n"
|
||||
"External edges can be either defining or construction geometries.\n"
|
||||
"You can use the toggle construction tool.");
|
||||
sWhatsThis = "Sketcher_Intersection";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_Intersection";
|
||||
sAccel = "G, I";
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
CONSTRUCTION_UPDATE_ACTION(CmdSketcherIntersection, "Sketcher_Intersection")
|
||||
|
||||
void CmdSketcherIntersection::activated(int iMsg)
|
||||
{
|
||||
ActivateHandler(getActiveGuiDocument(), std::make_unique<DrawSketchHandlerExternal>(true));
|
||||
}
|
||||
|
||||
bool CmdSketcherIntersection::isActive(void)
|
||||
{
|
||||
return isCommandActive(getActiveGuiDocument());
|
||||
}
|
||||
|
||||
// ======================================================================================
|
||||
|
||||
DEF_STD_CMD_AU(CmdSketcherCarbonCopy)
|
||||
@@ -2069,6 +2160,8 @@ void CreateSketcherCommandsCreateGeo()
|
||||
rcCmdMgr.addCommand(new CmdSketcherSplit());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCompCurveEdition());
|
||||
rcCmdMgr.addCommand(new CmdSketcherExternal());
|
||||
rcCmdMgr.addCommand(new CmdSketcherIntersection());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCompExternal());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCarbonCopy());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCompLine());
|
||||
}
|
||||
|
||||
@@ -116,7 +116,9 @@ public:
|
||||
class DrawSketchHandlerExternal: public DrawSketchHandler
|
||||
{
|
||||
public:
|
||||
DrawSketchHandlerExternal() = default;
|
||||
DrawSketchHandlerExternal(bool intersection = false)
|
||||
: intersection(intersection)
|
||||
{}
|
||||
~DrawSketchHandlerExternal() override
|
||||
{
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
@@ -163,10 +165,11 @@ public:
|
||||
Gui::Command::openCommand(
|
||||
QT_TRANSLATE_NOOP("Command", "Add external geometry"));
|
||||
Gui::cmdAppObjectArgs(sketchgui->getObject(),
|
||||
"addExternal(\"%s\",\"%s\", %s)",
|
||||
"addExternal(\"%s\",\"%s\", %s, %s)",
|
||||
msg.pObjectName,
|
||||
msg.pSubName,
|
||||
isConstructionMode() ? "False" : "True");
|
||||
isConstructionMode() ? "False" : "True",
|
||||
intersection ? "True" : "False");
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
@@ -214,6 +217,10 @@ private:
|
||||
|
||||
QString getCrosshairCursorSVGName() const override
|
||||
{
|
||||
if (intersection) {
|
||||
return QString::fromLatin1("Sketcher_Pointer_External_Intersection");
|
||||
}
|
||||
|
||||
return QString::fromLatin1("Sketcher_Pointer_External");
|
||||
}
|
||||
|
||||
@@ -222,6 +229,8 @@ private:
|
||||
Q_UNUSED(sketchgui);
|
||||
setAxisPickStyle(true);
|
||||
}
|
||||
|
||||
bool intersection;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -200,6 +200,8 @@
|
||||
<file>icons/geometry/Sketcher_Extend.svg</file>
|
||||
<file>icons/geometry/Sketcher_External.svg</file>
|
||||
<file>icons/geometry/Sketcher_External_Constr.svg</file>
|
||||
<file>icons/geometry/Sketcher_Intersection.svg</file>
|
||||
<file>icons/geometry/Sketcher_Intersection_Constr.svg</file>
|
||||
<file>icons/geometry/Sketcher_Split.svg</file>
|
||||
<file>icons/geometry/Sketcher_ToggleConstruction.svg</file>
|
||||
<file>icons/geometry/Sketcher_ToggleConstruction_Constr.svg</file>
|
||||
@@ -251,6 +253,7 @@
|
||||
<file>icons/pointers/Sketcher_Pointer_Create_Symmetry.svg</file>
|
||||
<file>icons/pointers/Sketcher_Pointer_Extension.svg</file>
|
||||
<file>icons/pointers/Sketcher_Pointer_External.svg</file>
|
||||
<file>icons/pointers/Sketcher_Pointer_External_Intersection.svg</file>
|
||||
<file>icons/pointers/Sketcher_Pointer_Heptagon.svg</file>
|
||||
<file>icons/pointers/Sketcher_Pointer_Hexagon.svg</file>
|
||||
<file>icons/pointers/Sketcher_Pointer_InsertKnot.svg</file>
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
id="svg2869"
|
||||
version="1.1"
|
||||
viewBox="0 0 64 64"
|
||||
sodipodi:docname="Sketcher_Intersection.svg"
|
||||
inkscape:version="1.1-beta1 (77e7b44db3, 2021-03-28)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview71"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
objecttolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
guidetolerance="10.0"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.9414063"
|
||||
inkscape:cx="-202.45418"
|
||||
inkscape:cy="55.245684"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="1571"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2869" />
|
||||
<defs
|
||||
id="defs2871">
|
||||
<linearGradient
|
||||
id="linearGradient5">
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop20" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch18">
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop18" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch15">
|
||||
<stop
|
||||
style="stop-color:#3d0000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop15" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5-1">
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3836-9">
|
||||
<stop
|
||||
style="stop-color:#a40000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3838-8" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3840-1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3836-9-3">
|
||||
<stop
|
||||
style="stop-color:#a40000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3838-8-5" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3840-1-6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="5"
|
||||
x2="-22"
|
||||
y1="18"
|
||||
x1="-18"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3082"
|
||||
xlink:href="#linearGradient3836-9-3" />
|
||||
<linearGradient
|
||||
id="linearGradient3836-9-7">
|
||||
<stop
|
||||
style="stop-color:#a40000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3838-8-0" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3840-1-9" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="5"
|
||||
x2="-22"
|
||||
y1="18"
|
||||
x1="-18"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3082-3"
|
||||
xlink:href="#linearGradient3836-9-7" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9-3"
|
||||
id="linearGradient3801-1-3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5"
|
||||
gradientTransform="matrix(0.76342439,0,0,0.75750425,-4.596389,2.7525637)" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9-3"
|
||||
id="linearGradient3801-1-3-2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5"
|
||||
gradientTransform="matrix(0.84956703,0,0,0.84301394,-2.927337,1.7790378)" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9-3"
|
||||
id="linearGradient34"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.82607043,0,0,0.82533448,-4.0098079,1.346708)"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3838"
|
||||
id="linearGradient3844"
|
||||
x1="36"
|
||||
y1="1039.3622"
|
||||
x2="32"
|
||||
y2="1003.3622"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(2.0563921e-6,-988.36218)" />
|
||||
<linearGradient
|
||||
id="linearGradient3838">
|
||||
<stop
|
||||
style="stop-color:#d3d7cf;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3840" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3842" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3830"
|
||||
id="linearGradient3836"
|
||||
x1="36"
|
||||
y1="1037.3622"
|
||||
x2="32"
|
||||
y2="1005.3622"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(2.0563921e-6,-988.36218)" />
|
||||
<linearGradient
|
||||
id="linearGradient3830">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3832" />
|
||||
<stop
|
||||
style="stop-color:#d3d7cf;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3834" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="10.504496"
|
||||
y1="16.48678"
|
||||
x2="5.9349072"
|
||||
y2="1.6356685"
|
||||
id="linearGradient-1"
|
||||
gradientTransform="scale(0.99999018,1.0000098)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#A40000"
|
||||
offset="0%"
|
||||
id="stop6-9" />
|
||||
<stop
|
||||
stop-color="#EF2929"
|
||||
offset="100%"
|
||||
id="stop8" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3815"
|
||||
id="linearGradient3856"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="80"
|
||||
y1="58"
|
||||
x2="79"
|
||||
y2="42"
|
||||
gradientTransform="matrix(-0.00939458,-1.2882215,1.6774889,-0.00721454,-1.7046467,126.12227)" />
|
||||
<linearGradient
|
||||
id="linearGradient3815">
|
||||
<stop
|
||||
style="stop-color:#3465a4;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3817" />
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3819" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3841"
|
||||
id="linearGradient3858"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="109"
|
||||
y1="51"
|
||||
x2="105"
|
||||
y2="38"
|
||||
gradientTransform="translate(-16.823373,6.2895086)" />
|
||||
<linearGradient
|
||||
id="linearGradient3841">
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3843" />
|
||||
<stop
|
||||
style="stop-color:#3465a4;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3845" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="5"
|
||||
x2="-22"
|
||||
y1="18"
|
||||
x1="-18"
|
||||
gradientTransform="matrix(0.77114848,0,0,0.77113937,-4.4090973,2.5859051)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3898"
|
||||
xlink:href="#linearGradient3836-9-3" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3815"
|
||||
id="linearGradient3978"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-15"
|
||||
y1="37"
|
||||
x2="-19"
|
||||
y2="37"
|
||||
gradientTransform="rotate(15,69.468151,244.38323)" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9-3"
|
||||
id="linearGradient25"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.82607043,0,0,0.82533448,-4.0098079,1.346708)"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3815"
|
||||
id="linearGradient3748"
|
||||
x1="21.865803"
|
||||
y1="14.823394"
|
||||
x2="59.167919"
|
||||
y2="14.823394"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-5.3545817,7.6494024)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3815"
|
||||
id="linearGradient3783"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="rotate(180,37.057105,31.362549)"
|
||||
x1="59.092896"
|
||||
y1="15.588334"
|
||||
x2="21.260881"
|
||||
y2="15.673326" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9"
|
||||
id="linearGradient25-8"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.82607043,0,0,0.82533448,-4.0098079,1.346708)"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata2874">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[maxwxyz]</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Sketcher/Gui/Resources/icons/Sketcher_CreateArc.svg</dc:identifier>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:date>2023-12-19</dc:date>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
style="fill:url(#linearGradient3783);fill-opacity:1;stroke:#0b1521;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 51.250996,35.357237 49.496052,59.704648 15.946284,59.848939 17.508632,35.017264"
|
||||
id="path3606-0" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 49.178749,35.190901 47.632004,57.712779 18.067528,57.86373 19.505976,35.059761"
|
||||
id="path4286-5"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
id="path3027"
|
||||
d="M 1.5850321,44.532846 24.798304,24.100465 61.939537,28.186942 38.726265,48.619323 Z"
|
||||
style="fill:#d21919;fill-opacity:0.36831275;stroke:#d21919;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3748);fill-opacity:1;stroke:#0b1521;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 17.508632,35.017264 19.263576,10.669853 52.813344,10.525562 51.250996,35.357237"
|
||||
id="path3606" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 19.505976,35.059761 1.62696,-22.472403 29.282936,0.05622 -1.154486,22.652497"
|
||||
id="path4286"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#151819;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 18.462151,34.4834 32.788845,0.873837"
|
||||
id="path3921"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#d3d7cf;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 18.462151,34.4834 32.788845,0.873837"
|
||||
id="path3921-4"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 18.15845,33.483274 33.405046,0.873838"
|
||||
id="path11"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<g
|
||||
transform="matrix(0.52286042,0,0,0.52286032,62.255136,29.78816)"
|
||||
id="g25"
|
||||
style="stroke-width:1.2842">
|
||||
<path
|
||||
style="fill:none;stroke:#2e0000;stroke-width:2.56841;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path24"
|
||||
d="M -26.310778,5.3580033 A 8.3519646,8.3515832 0.02039876 1 1 -13.623399,16.222662 8.3519646,8.3515832 0.02039876 1 1 -26.310778,5.3580033 Z" />
|
||||
<path
|
||||
style="fill:url(#linearGradient25);fill-opacity:1;stroke:#ef2929;stroke-width:2.56842;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path25"
|
||||
d="m -24.358888,7.0362241 a 5.782493,5.7773415 0 1 1 8.784093,7.5158349 5.782493,5.7773415 0 0 1 -8.784093,-7.5158349 z" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.52286042,0,0,0.52286032,27.608659,28.950461)"
|
||||
id="g25-7"
|
||||
style="stroke-width:1.2842">
|
||||
<path
|
||||
style="fill:none;stroke:#2e0000;stroke-width:2.56841;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path24-7"
|
||||
d="M -26.310778,5.3580033 A 8.3519646,8.3515832 0.02039876 1 1 -13.623399,16.222662 8.3519646,8.3515832 0.02039876 1 1 -26.310778,5.3580033 Z" />
|
||||
<path
|
||||
style="fill:url(#linearGradient25-8);fill-opacity:1;stroke:#ef2929;stroke-width:2.56842;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path25-2"
|
||||
d="m -24.358888,7.0362241 a 5.782493,5.7773415 0 1 1 8.784093,7.5158349 5.782493,5.7773415 0 0 1 -8.784093,-7.5158349 z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,399 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
id="svg2869"
|
||||
version="1.1"
|
||||
viewBox="0 0 64 64"
|
||||
sodipodi:docname="Sketcher_Intersection_Constr.svg"
|
||||
inkscape:version="1.1-beta1 (77e7b44db3, 2021-03-28)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview71"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
objecttolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
guidetolerance="10.0"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8.3195534"
|
||||
inkscape:cx="45.134635"
|
||||
inkscape:cy="32.633963"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="1571"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2869" />
|
||||
<defs
|
||||
id="defs2871">
|
||||
<linearGradient
|
||||
id="linearGradient5">
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop19" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop20" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch18">
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop18" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch15">
|
||||
<stop
|
||||
style="stop-color:#3d0000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop15" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5-1">
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3836-9">
|
||||
<stop
|
||||
style="stop-color:#a40000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3838-8" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3840-1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3836-9-3">
|
||||
<stop
|
||||
style="stop-color:#a40000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3838-8-5" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3840-1-6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="5"
|
||||
x2="-22"
|
||||
y1="18"
|
||||
x1="-18"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3082"
|
||||
xlink:href="#linearGradient3836-9-3" />
|
||||
<linearGradient
|
||||
id="linearGradient3836-9-7">
|
||||
<stop
|
||||
style="stop-color:#a40000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3838-8-0" />
|
||||
<stop
|
||||
style="stop-color:#ef2929;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3840-1-9" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="5"
|
||||
x2="-22"
|
||||
y1="18"
|
||||
x1="-18"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3082-3"
|
||||
xlink:href="#linearGradient3836-9-7" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9-3"
|
||||
id="linearGradient3801-1-3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5"
|
||||
gradientTransform="matrix(0.76342439,0,0,0.75750425,-4.596389,2.7525637)" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9-3"
|
||||
id="linearGradient3801-1-3-2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5"
|
||||
gradientTransform="matrix(0.84956703,0,0,0.84301394,-2.927337,1.7790378)" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9-3"
|
||||
id="linearGradient34"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.82607043,0,0,0.82533448,-4.0098079,1.346708)"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3838"
|
||||
id="linearGradient3844"
|
||||
x1="36"
|
||||
y1="1039.3622"
|
||||
x2="32"
|
||||
y2="1003.3622"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(2.0563921e-6,-988.36218)" />
|
||||
<linearGradient
|
||||
id="linearGradient3838">
|
||||
<stop
|
||||
style="stop-color:#d3d7cf;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3840" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3842" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3830"
|
||||
id="linearGradient3836"
|
||||
x1="36"
|
||||
y1="1037.3622"
|
||||
x2="32"
|
||||
y2="1005.3622"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(2.0563921e-6,-988.36218)" />
|
||||
<linearGradient
|
||||
id="linearGradient3830">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3832" />
|
||||
<stop
|
||||
style="stop-color:#d3d7cf;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3834" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="10.504496"
|
||||
y1="16.48678"
|
||||
x2="5.9349072"
|
||||
y2="1.6356685"
|
||||
id="linearGradient-1"
|
||||
gradientTransform="scale(0.99999018,1.0000098)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#A40000"
|
||||
offset="0%"
|
||||
id="stop6-9" />
|
||||
<stop
|
||||
stop-color="#EF2929"
|
||||
offset="100%"
|
||||
id="stop8" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3815"
|
||||
id="linearGradient3856"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="80"
|
||||
y1="58"
|
||||
x2="79"
|
||||
y2="42"
|
||||
gradientTransform="matrix(-0.00939458,-1.2882215,1.6774889,-0.00721454,-1.7046467,126.12227)" />
|
||||
<linearGradient
|
||||
id="linearGradient3815">
|
||||
<stop
|
||||
style="stop-color:#3465a4;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3817" />
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3819" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3841"
|
||||
id="linearGradient3858"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="109"
|
||||
y1="51"
|
||||
x2="105"
|
||||
y2="38"
|
||||
gradientTransform="translate(-16.823373,6.2895086)" />
|
||||
<linearGradient
|
||||
id="linearGradient3841">
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3843" />
|
||||
<stop
|
||||
style="stop-color:#3465a4;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3845" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="5"
|
||||
x2="-22"
|
||||
y1="18"
|
||||
x1="-18"
|
||||
gradientTransform="matrix(0.77114848,0,0,0.77113937,-4.4090973,2.5859051)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3898"
|
||||
xlink:href="#linearGradient3836-9-3" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3815"
|
||||
id="linearGradient3978"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-15"
|
||||
y1="37"
|
||||
x2="-19"
|
||||
y2="37"
|
||||
gradientTransform="rotate(15,69.468151,244.38323)" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9-3"
|
||||
id="linearGradient25"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.82607043,0,0,0.82533448,-4.0098079,1.346708)"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3815"
|
||||
id="linearGradient3748"
|
||||
x1="21.865803"
|
||||
y1="14.823394"
|
||||
x2="59.167919"
|
||||
y2="14.823394"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-5.3545817,7.6494024)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3815"
|
||||
id="linearGradient3783"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="rotate(180,37.057105,31.362549)"
|
||||
x1="59.092896"
|
||||
y1="15.588334"
|
||||
x2="21.260881"
|
||||
y2="15.673326" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3836-9"
|
||||
id="linearGradient25-8"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.82607043,0,0,0.82533448,-4.0098079,1.346708)"
|
||||
x1="-18"
|
||||
y1="18"
|
||||
x2="-22"
|
||||
y2="5" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata2874">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[maxwxyz]</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Sketcher/Gui/Resources/icons/Sketcher_CreateArc.svg</dc:identifier>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:date>2023-12-19</dc:date>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
style="fill:url(#linearGradient3783);fill-opacity:1;stroke:#0b1521;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 51.250996,35.357237 49.496052,59.704648 15.946284,59.848939 17.508632,35.017264"
|
||||
id="path3606-0" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 49.178749,35.190901 47.632004,57.712779 18.067528,57.86373 19.505976,35.059761"
|
||||
id="path4286-5"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
id="path3027"
|
||||
d="M 1.5850321,44.532846 24.798304,24.100465 61.939537,28.186942 38.726265,48.619323 Z"
|
||||
style="fill:#d21919;fill-opacity:0.36831275;stroke:#d21919;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3748);fill-opacity:1;stroke:#0b1521;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 17.508632,35.017264 19.263576,10.669853 52.813344,10.525562 51.250996,35.357237"
|
||||
id="path3606" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 19.505976,35.059761 1.62696,-22.472403 29.282936,0.05622 -1.154486,22.652497"
|
||||
id="path4286"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#0b1521;stroke-width:8;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 18.462151,34.4834 32.788845,0.873837"
|
||||
id="path3921"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;stroke:#3465a4;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 18.462151,34.4834 32.788845,0.873837"
|
||||
id="path3921-4"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 18.15845,33.483274 33.405046,0.873838"
|
||||
id="path11"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<g
|
||||
transform="matrix(0.52286042,0,0,0.52286032,62.255136,29.78816)"
|
||||
id="g25"
|
||||
style="stroke-width:1.2842">
|
||||
<path
|
||||
style="fill:none;stroke:#2e0000;stroke-width:2.56841;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path24"
|
||||
d="M -26.310778,5.3580033 A 8.3519646,8.3515832 0.02039876 1 1 -13.623399,16.222662 8.3519646,8.3515832 0.02039876 1 1 -26.310778,5.3580033 Z" />
|
||||
<path
|
||||
style="fill:url(#linearGradient25);fill-opacity:1;stroke:#ef2929;stroke-width:2.56842;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path25"
|
||||
d="m -24.358888,7.0362241 a 5.782493,5.7773415 0 1 1 8.784093,7.5158349 5.782493,5.7773415 0 0 1 -8.784093,-7.5158349 z" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.52286042,0,0,0.52286032,27.608659,28.950461)"
|
||||
id="g25-7"
|
||||
style="stroke-width:1.2842">
|
||||
<path
|
||||
style="fill:none;stroke:#2e0000;stroke-width:2.56841;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path24-7"
|
||||
d="M -26.310778,5.3580033 A 8.3519646,8.3515832 0.02039876 1 1 -13.623399,16.222662 8.3519646,8.3515832 0.02039876 1 1 -26.310778,5.3580033 Z" />
|
||||
<path
|
||||
style="fill:url(#linearGradient25-8);fill-opacity:1;stroke:#ef2929;stroke-width:2.56842;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path25-2"
|
||||
d="m -24.358888,7.0362241 a 5.782493,5.7773415 0 1 1 8.784093,7.5158349 5.782493,5.7773415 0 0 1 -8.784093,-7.5158349 z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
id="svg12"
|
||||
width="64"
|
||||
height="64"
|
||||
version="1.1"
|
||||
sodipodi:docname="Sketcher_Pointer_External_Intersection.svg"
|
||||
inkscape:version="1.1-beta1 (77e7b44db3, 2021-03-28)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="12.3125"
|
||||
inkscape:cy="38.5625"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg12"
|
||||
objecttolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
guidetolerance="10.0"
|
||||
inkscape:pageshadow="0"
|
||||
showgrid="false" />
|
||||
<metadata
|
||||
id="metadata18">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs16">
|
||||
<inkscape:path-effect
|
||||
effect="dashed_stroke"
|
||||
id="path-effect1"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
numberdashes="4"
|
||||
holefactor="0"
|
||||
splitsegments="true"
|
||||
halfextreme="true"
|
||||
unifysegment="false"
|
||||
message="Add <b>"Fill Between Many LPE"</b> to add fill." />
|
||||
</defs>
|
||||
<path
|
||||
id="path6161"
|
||||
style="fill:none;stroke:#d60000;stroke-width:2;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 61.303538,37.170339 H 21.900546 L 5.8602162,55.892161 H 47.78452 L 61.303538,37.170339 v 0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<g
|
||||
id="g1290"
|
||||
transform="translate(-10.625,20.75)">
|
||||
<path
|
||||
style="fill:#a76635;stroke:#cc0000;stroke-width:2;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
d="m 33.483443,25.311263 h 24"
|
||||
id="path1" />
|
||||
<circle
|
||||
cx="33.483452"
|
||||
cy="25.311251"
|
||||
id="circle4755"
|
||||
style="fill:none;stroke:#cc0000;stroke-width:2"
|
||||
r="4" />
|
||||
<circle
|
||||
cx="57.483452"
|
||||
cy="25.311251"
|
||||
id="circle4755-2"
|
||||
style="fill:none;stroke:#cc0000;stroke-width:2"
|
||||
r="4" />
|
||||
</g>
|
||||
<g
|
||||
style="stroke:#ffffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter"
|
||||
id="crosshair">
|
||||
<path
|
||||
id="path9"
|
||||
d="m16,3v9m0,8v9m-13-13h9m8,0h9" />
|
||||
</g>
|
||||
<path
|
||||
id="path6161-0"
|
||||
style="fill:none;stroke:#d60000;stroke-width:2;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 23.764089,24.398641 -2.125,37.652992 24.721822,0.16533 1.375,-37.924304 -23.971822,0.105982"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -538,6 +538,7 @@ inline void SketcherAddWorkbenchTools<Gui::MenuItem>(Gui::MenuItem& consaccel)
|
||||
SketcherAddWorkspaceFillets(consaccel);
|
||||
SketcherAddWorkspaceCurveEdition(consaccel);
|
||||
consaccel << "Sketcher_External"
|
||||
<< "Sketcher_Intersection"
|
||||
<< "Sketcher_CarbonCopy"
|
||||
<< "Separator"
|
||||
<< "Sketcher_SelectOrigin"
|
||||
@@ -564,7 +565,7 @@ inline void SketcherAddWorkbenchTools<Gui::ToolBarItem>(Gui::ToolBarItem& consac
|
||||
{
|
||||
SketcherAddWorkspaceFillets(consaccel);
|
||||
SketcherAddWorkspaceCurveEdition(consaccel);
|
||||
consaccel << "Sketcher_External"
|
||||
consaccel << "Sketcher_CompExternal"
|
||||
<< "Sketcher_CarbonCopy"
|
||||
<< "Separator"
|
||||
<< "Sketcher_Translate"
|
||||
|
||||
Reference in New Issue
Block a user