mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 13:46:54 +00:00
SvgSerializer: Support full circles and ellipses
Use <circle> and <ellipse> to create a valid SVG for these geometries. Limit to only the *first* edge. I am not sure whether there are scenarios with multiple edges like this: 1. One or more straight line pieces or arc segments 2. A full closed circle 3. More straight lines or arc segments If there is, we are keeping the original behavior here.
This commit is contained in:
committed by
Thomas Krijnen
parent
aec9d32ce7
commit
ce970792ba
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <gp_Pln.hxx>
|
#include <gp_Pln.hxx>
|
||||||
#include <gp_Trsf.hxx>
|
#include <gp_Trsf.hxx>
|
||||||
|
#include <gp_Circ.hxx>
|
||||||
|
#include <gp_Elips.hxx>
|
||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
#include <TopoDS_Edge.hxx>
|
#include <TopoDS_Edge.hxx>
|
||||||
#include <TopExp_Explorer.hxx>
|
#include <TopExp_Explorer.hxx>
|
||||||
@@ -76,10 +78,64 @@ void SvgSerializer::write(path_object& p, const TopoDS_Wire& wire) {
|
|||||||
bool conical = (ty == STANDARD_TYPE(Geom_Circle) || ty == STANDARD_TYPE(Geom_Ellipse));
|
bool conical = (ty == STANDARD_TYPE(Geom_Circle) || ty == STANDARD_TYPE(Geom_Ellipse));
|
||||||
bool closed = ALMOST_THE_SAME(u1 + PI2, u2);
|
bool closed = ALMOST_THE_SAME(u1 + PI2, u2);
|
||||||
if (conical && closed) {
|
if (conical && closed) {
|
||||||
std::stringstream ss;
|
if (first) {
|
||||||
ss << "Full circles and ellipses currently not supported (id "
|
if (ty == STANDARD_TYPE(Geom_Circle)) {
|
||||||
<< p.first << ")";
|
Handle(Geom_Circle) circle = Handle(Geom_Circle)::DownCast(curve);
|
||||||
Logger::Warning(ss.str());
|
double r = circle->Radius();
|
||||||
|
gp_Circ c = circle->Circ();
|
||||||
|
gp_Pnt center = c.Location();
|
||||||
|
path.add(" <circle style=\"stroke:black; fill:none;\" r=\"");
|
||||||
|
radii.push_back(path.add(r));
|
||||||
|
path.add("\" cx=\"");
|
||||||
|
xcoords.push_back(path.add(center.X()));
|
||||||
|
path.add("\" cy=\"");
|
||||||
|
ycoords.push_back(path.add(center.Y()));
|
||||||
|
|
||||||
|
growBoundingBox(center.X() - r, center.Y() - r);
|
||||||
|
growBoundingBox(center.X() + r, center.Y() + r);
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
continue;
|
||||||
|
} else if (ty == STANDARD_TYPE(Geom_Ellipse)) {
|
||||||
|
Handle(Geom_Ellipse) ellipse = Handle(Geom_Ellipse)::DownCast(curve);
|
||||||
|
gp_Elips e = ellipse->Elips();
|
||||||
|
gp_Pnt center = e.Location();
|
||||||
|
|
||||||
|
// Write the ellipse with major radius along X axis:
|
||||||
|
path.add(" <ellipse style=\"stroke:black; fill:none;\" rx=\"");
|
||||||
|
radii.push_back(path.add(e.MajorRadius()));
|
||||||
|
path.add("\" ry\"");
|
||||||
|
radii.push_back(path.add(e.MinorRadius()));
|
||||||
|
path.add("\" cx=\"");
|
||||||
|
xcoords.push_back(path.add(center.X()));
|
||||||
|
path.add("\" cy=\"");
|
||||||
|
ycoords.push_back(path.add(center.Y()));
|
||||||
|
path.add("\"");
|
||||||
|
|
||||||
|
// Rotate it with "transform":
|
||||||
|
gp_Ax1 major_axis = e.XAxis();
|
||||||
|
double z_rotation = major_axis.Direction().AngleWithRef(gp_Dir(1., 0., 0.), gp_Dir(0., 0., 1.));
|
||||||
|
path.add(" transform=\"rotate(");
|
||||||
|
path.add(z_rotation);
|
||||||
|
path.add(" ");
|
||||||
|
path.add(center.X());
|
||||||
|
path.add(" ");
|
||||||
|
path.add(center.Y());
|
||||||
|
|
||||||
|
// Bounding box:
|
||||||
|
// More important to have all geometry in bounding box than to be minimal
|
||||||
|
growBoundingBox(center.X() - e.MajorRadius(), center.Y() - e.MajorRadius());
|
||||||
|
growBoundingBox(center.X() + e.MajorRadius(), center.Y() + e.MajorRadius());
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Skipping full circle/ellipse inside aggregated <path> (id "
|
||||||
|
<< p.first << ")";
|
||||||
|
Logger::Warning(ss.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool reversed = edge.Orientation() == TopAbs_REVERSED;
|
const bool reversed = edge.Orientation() == TopAbs_REVERSED;
|
||||||
|
|||||||
Reference in New Issue
Block a user