Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add check in Extrude(), replace replace codecvt_utf8_utf16 #1282

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ examples/nodejs/*.ifc
tests/ifcfiles/private/*.ifc
tests/ifcfiles/private/*.stl
tests/ifcfiles/created.ifc
src/cpp/_deps/
26 changes: 23 additions & 3 deletions src/cpp/web-ifc/geometry/IfcGeometryLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,9 +909,15 @@ namespace webifc::geometry
case schema::IFCCURVESTYLE:
{
_loader.MoveToArgumentOffset(expressID, 3);
auto foundColor = GetColor(_loader.GetRefArgument());
if (foundColor)
return foundColor;
// argument 3 (CurveColour) is optional, so check if it is set
auto tt = _loader.GetTokenType();
if (tt == parsing::REF)
{
_loader.StepBack();
auto foundColor = GetColor(_loader.GetRefArgument());
if (foundColor)
return foundColor;
}
return {};
}
case schema::IFCFILLAREASTYLEHATCHING:
Expand Down Expand Up @@ -1322,6 +1328,20 @@ namespace webifc::geometry

switch (lineType)
{

case schema::IFCEDGE:
{
_loader.MoveToArgumentOffset(expressID, 0);
glm::dvec3 p1 = GetVertexPoint(_loader.GetRefArgument());
_loader.MoveToArgumentOffset(expressID, 1);
glm::dvec3 p2 = GetVertexPoint(_loader.GetRefArgument());

IfcCurve curve;
curve.points.push_back(p1);
curve.points.push_back(p2);

return curve;
}
case schema::IFCEDGECURVE:
{
IfcTrimmingArguments ts;
Expand Down
140 changes: 136 additions & 4 deletions src/cpp/web-ifc/geometry/IfcGeometryProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,8 +641,10 @@ namespace webifc::geometry

return mesh;
}
case schema::IFCTOPOLOGYREPRESENTATION:
case schema::IFCSHAPEREPRESENTATION:
{
// IFCTOPOLOGYREPRESENTATION and IFCSHAPEREPRESENTATION are identical in attributes layout
_loader.MoveToArgumentOffset(expressID, 1);
auto type = _loader.GetStringArgument();

Expand Down Expand Up @@ -695,6 +697,54 @@ namespace webifc::geometry

return mesh;
}
case schema::IFCFACESURFACE:
{
IfcGeometry geometry;
_loader.MoveToArgumentOffset(expressID, 0);
auto bounds = _loader.GetSetArgument();

std::vector<IfcBound3D> bounds3D(bounds.size());

for (size_t i = 0; i < bounds.size(); i++)
{
uint32_t boundID = _loader.GetRefArgument(bounds[i]);
bounds3D[i] = _geometryLoader.GetBound(boundID);
}

TriangulateBounds(geometry, bounds3D, expressID);

_loader.MoveToArgumentOffset(expressID, 1);
auto surfRef = _loader.GetRefArgument();

auto surface = GetSurface(surfRef);

if (surface.BSplineSurface.Active)
{
TriangulateBspline(geometry, bounds3D, surface, _geometryLoader.GetLinearScalingFactor());
}
else if (surface.CylinderSurface.Active)
{
TriangulateCylindricalSurface(geometry, bounds3D, surface, _circleSegments);
}
else if (surface.RevolutionSurface.Active)
{
TriangulateRevolution(geometry, bounds3D, surface, _circleSegments);
}
else if (surface.ExtrusionSurface.Active)
{
TriangulateExtrusion(geometry, bounds3D, surface);
}
else
{
TriangulateBounds(geometry, bounds3D, expressID);
}

_expressIDToGeometry[expressID] = geometry;
mesh.expressID = expressID;
mesh.hasGeometry = true;

break;
}
case schema::IFCTRIANGULATEDIRREGULARNETWORK:
case schema::IFCTRIANGULATEDFACESET:
{
Expand Down Expand Up @@ -1015,6 +1065,7 @@ namespace webifc::geometry
return mesh;
}
case schema::IFCGEOMETRICSET:
case schema::IFCGEOMETRICCURVESET:
{
_loader.MoveToArgumentOffset(expressID, 0);
auto items = _loader.GetSetArgument();
Expand All @@ -1027,11 +1078,88 @@ namespace webifc::geometry

return mesh;
}
case schema::IFCBOUNDINGBOX:
// ignore bounding box
return mesh;

case schema::IFCCARTESIANPOINT:
{
// IfcCartesianPoint is derived from IfcRepresentationItem and can be used as representation item directly
IfcGeometry geom;
auto point = _geometryLoader.GetCartesianPoint3D(expressID);
geom.vertexData.push_back(point.x);
geom.vertexData.push_back(point.y);
geom.vertexData.push_back(point.z);
geom.vertexData.push_back(0); // needs to be 6 values per vertex
geom.vertexData.push_back(0);
geom.vertexData.push_back(1);
geom.indexData.push_back(0);

geom.numPoints = 1;
geom.isPolygon = true;
mesh.hasGeometry = true;
_expressIDToGeometry[expressID] = geom;

return mesh;
}
case schema::IFCEDGE:
{
// IfcEdge is derived from IfcRepresentationItem and can be used as representation item directly
IfcCurve edge = _geometryLoader.GetEdge(expressID);
IfcGeometry geom;

for (uint32_t i = 0; i < edge.points.size(); i++)
{
auto vert = edge.points[i];
geom.vertexData.push_back(vert.x);
geom.vertexData.push_back(vert.y);
geom.vertexData.push_back(vert.z);
geom.vertexData.push_back(0); // needs to be 6 values per vertex
geom.vertexData.push_back(0);
geom.vertexData.push_back(1);
geom.indexData.push_back(i);
}
geom.numPoints = edge.points.size();
geom.isPolygon = true;
mesh.hasGeometry = true;
_expressIDToGeometry[expressID] = geom;

return mesh;
}
case schema::IFCCIRCLE:
case schema::IFCPOLYLINE:
case schema::IFCINDEXEDPOLYCURVE:
case schema::IFCTRIMMEDCURVE:
// ignore polylines as meshes
return mesh;
{
auto lineProfileType = _loader.GetLineType(expressID);
IfcCurve curve = _geometryLoader.GetCurve(expressID, 3, false);

if (curve.points.size() > 0) {
IfcGeometry geom;

for (uint32_t i = 0; i < curve.points.size(); i++)
{
auto vert = curve.points[i];
geom.vertexData.push_back(vert.x);
geom.vertexData.push_back(vert.y);
geom.vertexData.push_back(vert.z);
geom.vertexData.push_back(0); // needs to be 6 values per vertex
geom.vertexData.push_back(0);
geom.vertexData.push_back(1);
geom.indexData.push_back(i);
}
geom.numPoints = curve.points.size();
geom.isPolygon = true;
mesh.hasGeometry = true;
_expressIDToGeometry[expressID] = geom;
}

return mesh;
}
case schema::IFCTEXTLITERAL:
case schema::IFCTEXTLITERALWITHEXTENT:
// TODO: save string of the text literal in IfcComposedMesh
return mesh;
default:
spdlog::error("[GetMesh()] unexpected mesh type {}", expressID, lineType);
break;
Expand Down Expand Up @@ -1429,15 +1557,19 @@ namespace webifc::geometry
return IfcSurface();
}

IfcFlatMesh IfcGeometryProcessor::GetFlatMesh(uint32_t expressID)
IfcFlatMesh IfcGeometryProcessor::GetFlatMesh(uint32_t expressID, bool applyLinearScalingFactor)
{
spdlog::debug("[GetFlatMesh({})]",expressID);
IfcFlatMesh flatMesh;
flatMesh.expressID = expressID;

IfcComposedMesh composedMesh = GetMesh(expressID);

glm::dmat4 mat = glm::scale(glm::dvec3(_geometryLoader.GetLinearScalingFactor()));
glm::dmat4 mat = glm::dmat4(1);
if (applyLinearScalingFactor)
{
mat = glm::scale(glm::dvec3(_geometryLoader.GetLinearScalingFactor()));;
}

AddComposedMeshToFlatMesh(flatMesh, composedMesh, _transformation * NormalizeIFC * mat);

Expand Down
2 changes: 1 addition & 1 deletion src/cpp/web-ifc/geometry/IfcGeometryProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace webifc::geometry
IfcGeometryProcessor(const webifc::parsing::IfcLoader &loader,const webifc::schema::IfcSchemaManager &schemaManager,uint16_t circleSegments,bool coordinateToOrigin);
IfcGeometry &GetGeometry(uint32_t expressID);
IfcGeometryLoader GetLoader() const;
IfcFlatMesh GetFlatMesh(uint32_t expressID);
IfcFlatMesh GetFlatMesh(uint32_t expressID, bool applyLinearScalingFactor = true);
IfcComposedMesh GetMesh(uint32_t expressID);
void SetTransformation(const std::array<double, 16> &val);
std::array<double, 16> GetFlatCoordinationMatrix() const;
Expand Down
8 changes: 4 additions & 4 deletions src/cpp/web-ifc/geometry/nurbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ namespace tinynurbs{

namespace webifc::geometry{

class IfcGeometry;
class IfcBound3D;
class BSpline;
class IfcSurface;
struct IfcGeometry;
struct IfcBound3D;
struct BSpline;
struct IfcSurface;

constexpr double rotations { 6.0 };
constexpr auto pi {glm::pi<double>()};
Expand Down
18 changes: 14 additions & 4 deletions src/cpp/web-ifc/geometry/operations/geometryutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ namespace webifc::geometry
// this is bad news, as it nans the points added to the final mesh
// also, it's hard to bail out now :/
// see curve.add() for more info on how this is currently "solved"
#if defined(_DEBUG)
printf("NaN perp!\n");
#endif
}

glm::dvec3 u1 = glm::normalize(glm::cross(n1, p));
Expand Down Expand Up @@ -363,7 +365,9 @@ namespace webifc::geometry
// this is bad news, as it nans the points added to the final mesh
// also, it's hard to bail out now :/
// see curve.add() for more info on how this is currently "solved"
#if defined(_DEBUG)
printf("NaN perp!\n");
#endif
}

glm::dvec3 u1 = glm::normalize(glm::cross(n1, p));
Expand Down Expand Up @@ -820,6 +824,12 @@ namespace webifc::geometry
IfcGeometry geom;
std::vector<bool> holesIndicesHash;

// check if first point is equal to last point, otherwise the outer loop of the shape is not closed
glm::dvec3 lastToFirstPoint = profile.curve.points.front() - profile.curve.points.back();
if (glm::length(lastToFirstPoint) > 1e-8) {
profile.curve.points.push_back(profile.curve.points.front());
}

// build the caps
{
using Point = std::array<double, 2>;
Expand Down Expand Up @@ -947,12 +957,12 @@ namespace webifc::geometry

// this winding should be correct
geom.AddFace(geom.GetPoint(tl),
geom.GetPoint(br),
geom.GetPoint(bl));
geom.GetPoint(br),
geom.GetPoint(bl));

geom.AddFace(geom.GetPoint(tl),
geom.GetPoint(tr),
geom.GetPoint(br));
geom.GetPoint(tr),
geom.GetPoint(br));
}

return geom;
Expand Down
21 changes: 17 additions & 4 deletions src/cpp/web-ifc/geometry/operations/mesh_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,23 @@ namespace webifc::geometry
for (int r = 0; r < numRots - 1; r++)
{
int r1 = r + 1;
for (size_t s = 0; s < newPoints[r].size() - 1; s++)
{
geometry.AddFace(newPoints[r][s], newPoints[r][s + 1], newPoints[r1][s]);
geometry.AddFace(newPoints[r1][s], newPoints[r][s + 1], newPoints[r1][s + 1]);
if (r1 >= newPoints.size()) {
break;
}
const std::vector<glm::dvec3>& newPointsR = newPoints[r];
const std::vector<glm::dvec3>& newPointsR1 = newPoints[r1];
if (newPointsR.size() > 0) {
for (size_t s = 0; s < newPointsR.size() - 1; s++)
{
if (s + 1 >= newPointsR.size()) {
break;
}
if (s + 1 >= newPointsR1.size()) {
break;
}
geometry.AddFace(newPointsR[s], newPointsR[s + 1], newPointsR1[s]);
geometry.AddFace(newPointsR1[s], newPointsR[s + 1], newPointsR1[s + 1]);
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/cpp/web-ifc/geometry/representation/IfcGeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ namespace webifc::geometry {
std::vector<uint32_t> indexData;
std::vector<uint32_t> planeData;
std::vector<Plane> planes;


bool isPolygon = false;
bool hasPlanes = false;
uint32_t numPoints = 0;
uint32_t numFaces = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/cpp/web-ifc/parsing/IfcLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,8 +666,8 @@ namespace webifc::parsing {
if (t==SET_BEGIN) {
StepBack();
GetSetArgument();
noArguments++;
continue;
noArguments++;
continue;
}
if (t == IfcTokenType::STRING || t == IfcTokenType::INTEGER || t == IfcTokenType::REAL || t == IfcTokenType::LABEL || t == IfcTokenType::ENUM) {
uint16_t length = _tokenStream->Read<uint16_t>();
Expand Down
Loading
Loading