mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-27 10:51:13 +00:00
project() more efficiently onto planar surfaces
This commit is contained in:
@@ -2748,7 +2748,19 @@ bool IfcGeom::Kernel::split_solid_by_shell(const TopoDS_Shape& input, const Topo
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape& shp, double& u1, double& v1, double& u2, double& v2, double widen) {
|
bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape& shp, double& u1, double& v1, double& u2, double& v2, double widen) {
|
||||||
ShapeAnalysis_Surface sas(srf);
|
// @todo std::unique_ptr for C++11
|
||||||
|
ShapeAnalysis_Surface* sas = 0;
|
||||||
|
Handle(Geom_Plane) pln;
|
||||||
|
|
||||||
|
if (srf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
|
||||||
|
// Optimize projection for specific cases
|
||||||
|
pln = Handle(Geom_Plane)::DownCast(srf);
|
||||||
|
} else if (srf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface) && Handle(Geom_OffsetSurface)::DownCast(srf)->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
|
||||||
|
// For an offset planar surface the projected UV coords are the same as the basis surface
|
||||||
|
pln = Handle(Geom_Plane)::DownCast(Handle(Geom_OffsetSurface)::DownCast(srf)->BasisSurface());
|
||||||
|
} else {
|
||||||
|
sas = new ShapeAnalysis_Surface(srf);
|
||||||
|
}
|
||||||
|
|
||||||
u1 = v1 = +std::numeric_limits<double>::infinity();
|
u1 = v1 = +std::numeric_limits<double>::infinity();
|
||||||
u2 = v2 = -std::numeric_limits<double>::infinity();
|
u2 = v2 = -std::numeric_limits<double>::infinity();
|
||||||
@@ -2759,7 +2771,14 @@ bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape
|
|||||||
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()));
|
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()));
|
||||||
median.ChangeCoord() += p.XYZ();
|
median.ChangeCoord() += p.XYZ();
|
||||||
|
|
||||||
const gp_Pnt2d uv = sas.ValueOfUV(p, 1e-3);
|
gp_Pnt2d uv;
|
||||||
|
if (sas) {
|
||||||
|
uv = sas->ValueOfUV(p, 1e-3);
|
||||||
|
} else {
|
||||||
|
gp_Vec d = p.XYZ() - pln->Position().Location().XYZ();
|
||||||
|
uv.SetX(d.Dot(pln->Position().XDirection()));
|
||||||
|
uv.SetY(d.Dot(pln->Position().YDirection()));
|
||||||
|
}
|
||||||
|
|
||||||
if (uv.X() < u1) u1 = uv.X();
|
if (uv.X() < u1) u1 = uv.X();
|
||||||
if (uv.Y() < v1) v1 = uv.Y();
|
if (uv.Y() < v1) v1 = uv.Y();
|
||||||
@@ -2767,9 +2786,7 @@ bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape
|
|||||||
if (uv.Y() > v2) v2 = uv.Y();
|
if (uv.Y() > v2) v2 = uv.Y();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vertex_count == 0) {
|
if (vertex_count > 0) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a little bit of resolution so that the median is shifted towards the mass
|
// Add a little bit of resolution so that the median is shifted towards the mass
|
||||||
// of the curve. This helps to find the parameter ordering for conic surfaces.
|
// of the curve. This helps to find the parameter ordering for conic surfaces.
|
||||||
@@ -2785,7 +2802,14 @@ bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape
|
|||||||
}
|
}
|
||||||
|
|
||||||
median.ChangeCoord().Divide(vertex_count);
|
median.ChangeCoord().Divide(vertex_count);
|
||||||
const gp_Pnt2d uv = sas.ValueOfUV(median, 1e-3);
|
gp_Pnt2d uv;
|
||||||
|
if (sas) {
|
||||||
|
uv = sas->ValueOfUV(median, 1e-3);
|
||||||
|
} else {
|
||||||
|
gp_Vec d = median.XYZ() - pln->Position().Location().XYZ();
|
||||||
|
uv.SetX(d.Dot(pln->Position().XDirection()));
|
||||||
|
uv.SetY(d.Dot(pln->Position().YDirection()));
|
||||||
|
}
|
||||||
|
|
||||||
if (uv.X() < u1 || uv.X() > u2) {
|
if (uv.X() < u1 || uv.X() > u2) {
|
||||||
std::swap(u1, u2);
|
std::swap(u1, u2);
|
||||||
@@ -2796,7 +2820,10 @@ bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape
|
|||||||
v1 -= widen;
|
v1 -= widen;
|
||||||
v2 += widen;
|
v2 += widen;
|
||||||
|
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
delete sas;
|
||||||
|
return vertex_count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationItem* item) {
|
const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationItem* item) {
|
||||||
|
|||||||
Reference in New Issue
Block a user