diff --git a/.gitignore b/.gitignore index 902ea7f53b..507d42b612 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ __pycache__ .vscode # PyCharm files .idea +# OSX files +.DS_Store diff --git a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp index 9cb297835c..651a53fca3 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp @@ -23,6 +23,216 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRepresentation* l, Convers return part_succes; } -bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid*, cgal_shape_t&) { - throw std::runtime_error("Not implemented IfcExtrudedAreaSolid"); +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid *l, cgal_shape_t &shape) { + const double height = l->Depth() * getValue(GV_LENGTH_UNIT); + if (height < getValue(GV_PRECISION)) { + Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", l->entity); + return false; + } + + cgal_face_t face; + if ( !convert_face(l->SweptArea(),face) ) return false; + + cgal_placement_t trsf; + bool has_position = true; +#ifdef USE_IFC4 + has_position = l->hasPosition(); +#endif + if (has_position) { + IfcGeom::CgalKernel::convert(l->Position(), trsf); + } + + cgal_direction_t dir; + convert(l->ExtrudedDirection(),dir); +// std::cout << "Direction: " << dir << std::endl; + + std::list face_list; + face_list.push_back(face); + + for (std::vector::const_iterator current_vertex = face.outer.begin(); + current_vertex != face.outer.end(); + ++current_vertex) { + std::vector::const_iterator next_vertex = current_vertex; + ++next_vertex; + if (next_vertex == face.outer.end()) { + next_vertex = face.outer.begin(); + } cgal_face_t side_face; + side_face.outer.push_back(*next_vertex); + side_face.outer.push_back(*current_vertex); + side_face.outer.push_back(*current_vertex+height*dir); + side_face.outer.push_back(*next_vertex+height*dir); + face_list.push_back(side_face); + } + + cgal_face_t top_face; + for (std::vector::const_reverse_iterator vertex = face.outer.rbegin(); + vertex != face.outer.rend(); + ++vertex) { + top_face.outer.push_back(*vertex+height*dir); + } face_list.push_back(top_face); + + // Naive creation + cgal_shape_t polyhedron = CGAL::Polyhedron_3(); + PolyhedronBuilder builder(&face_list); + polyhedron.delegate(builder); + + // Stitch edges +// std::cout << "Before: " << polyhedron.size_of_vertices() << " vertices and " << polyhedron.size_of_facets() << " facets" << std::endl; + CGAL::Polygon_mesh_processing::stitch_borders(polyhedron); + if (!CGAL::Polygon_mesh_processing::is_outward_oriented(polyhedron)) { + CGAL::Polygon_mesh_processing::reverse_face_orientations(polyhedron); + } +// std::cout << "After: " << polyhedron.size_of_vertices() << " vertices and " << polyhedron.size_of_facets() << " facets" << std::endl; + + shape = polyhedron; + return true; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcCartesianPoint* l, cgal_point_t& point) { + std::vector xyz = l->Coordinates(); + if (xyz.size() == 3) { + point = Kernel::Point_3(xyz.size() ? (xyz[0]*getValue(GV_LENGTH_UNIT)) : 0.0f, + xyz.size() > 1 ? (xyz[1]*getValue(GV_LENGTH_UNIT)) : 0.0f, + xyz.size() > 2 ? (xyz[2]*getValue(GV_LENGTH_UNIT)) : 0.0f); +// std::cout << "Converted Point(" << point << ")" << std::endl; + return true; + } else { + throw std::runtime_error("Point without 3 coordinates"); + } +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcDirection* l, cgal_direction_t& dir) { +// IN_CACHE(IfcDirection,l,cgal_direction_t,dir) + std::vector xyz = l->DirectionRatios(); + dir = Kernel::Vector_3(xyz.size() ? xyz[0] : 0.0f, + xyz.size() > 1 ? xyz[1] : 0.0f, + xyz.size() > 2 ? xyz[2] : 0.0f); +// CACHE(IfcDirection,l,dir) + return true; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcAxis2Placement2D* l, cgal_placement_t& trsf) { + // IN_CACHE(IfcAxis2Placement3D,l,gp_Trsf,trsf) + cgal_point_t o; + cgal_direction_t axis = Kernel::Vector_3(0,0,1); + cgal_direction_t refDirection = Kernel::Vector_3(1,0,0); // TODO: Put identity for now. Check? + IfcGeom::CgalKernel::convert(l->Location(),o); + bool hasRef = l->hasRefDirection(); + if ( hasRef ) IfcGeom::CgalKernel::convert(l->RefDirection(),refDirection); + + // TODO: From Thomas' email. Should be checked. + Kernel::Vector_3 y = CGAL::cross_product(Kernel::Vector_3(0.0, 0.0, 1.0), refDirection); + trsf = Kernel::Aff_transformation_3(refDirection.cartesian(0), y.cartesian(0), 0.0, o.cartesian(0), + refDirection.cartesian(1), y.cartesian(1), 0.0, o.cartesian(1), + 0.0, y.cartesian(2), 1.0, 0.0); + + // CACHE(IfcAxis2Placement3D,l,trsf) + return true; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcAxis2Placement3D* l, cgal_placement_t& trsf) { +// IN_CACHE(IfcAxis2Placement3D,l,gp_Trsf,trsf) + cgal_point_t o; + cgal_direction_t axis = Kernel::Vector_3(0,0,1); + cgal_direction_t refDirection = Kernel::Vector_3(1,0,0); // TODO: Put identity for now. Check? + IfcGeom::CgalKernel::convert(l->Location(),o); + bool hasRef = l->hasRefDirection(); + if ( l->hasAxis() ) IfcGeom::CgalKernel::convert(l->Axis(),axis); + if ( hasRef ) IfcGeom::CgalKernel::convert(l->RefDirection(),refDirection); + +// std::cout << "Ref direction: " << refDirection << std::endl; +// std::cout << "Axis: " << axis << std::endl; +// std::cout << "Origin: " << o << std::endl; + + // TODO: From Thomas' email. Should be checked. + Kernel::Vector_3 y = CGAL::cross_product(axis, refDirection); + trsf = Kernel::Aff_transformation_3(refDirection.cartesian(0), y.cartesian(0), axis.cartesian(0), o.cartesian(0), + refDirection.cartesian(1), y.cartesian(1), axis.cartesian(1), o.cartesian(1), + refDirection.cartesian(2), y.cartesian(2), axis.cartesian(2), o.cartesian(2)); + +// for (int i = 0; i < 3; ++i) { +// for (int j = 0; j < 4; ++j) { +// std::cout << trsf.cartesian(i, j) << " "; +// } std::cout << std::endl; +// } + +// CACHE(IfcAxis2Placement3D,l,trsf) + return true; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcObjectPlacement* l, cgal_placement_t& trsf) { + // TODO: These macros don't work for the CGAL types. Need to check why. +// IN_CACHE(IfcObjectPlacement,l,cgal_placement_t,trsf) + if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) { + Logger::Message(Logger::LOG_ERROR, "Unsupported IfcObjectPlacement:", l->entity); + return false; + } + +// std::cout << "initial trsf (identity?)" << std::endl; +// for (int i = 0; i < 3; ++i) { +// for (int j = 0; j < 4; ++j) { +// std::cout << trsf.cartesian(i, j) << " "; +// } std::cout << std::endl; +// } + + IfcSchema::IfcLocalPlacement* current = (IfcSchema::IfcLocalPlacement*)l; + for (;;) { + cgal_placement_t trsf2; + + IfcSchema::IfcAxis2Placement* relplacement = current->RelativePlacement(); + if ( relplacement->is(IfcSchema::Type::IfcAxis2Placement3D) ) { + IfcGeom::CgalKernel::convert((IfcSchema::IfcAxis2Placement3D*)relplacement,trsf2); + +// std::cout << "trsf2" << std::endl; +// for (int i = 0; i < 3; ++i) { +// for (int j = 0; j < 4; ++j) { +// std::cout << trsf2.cartesian(i, j) << " "; +// } std::cout << std::endl; +// } + + trsf = trsf * trsf2; // TODO: I think it's fine, but maybe should it be the other way around? + +// std::cout << "trsf (after multiplication)" << std::endl; +// for (int i = 0; i < 3; ++i) { +// for (int j = 0; j < 4; ++j) { +// std::cout << trsf.cartesian(i, j) << " "; +// } std::cout << std::endl; +// } + } + if ( current->hasPlacementRelTo() ) { + IfcSchema::IfcObjectPlacement* relto = current->PlacementRelTo(); + if ( relto->is(IfcSchema::Type::IfcLocalPlacement) ) + current = (IfcSchema::IfcLocalPlacement*)current->PlacementRelTo(); + else break; + } else break; + } +// CACHE(IfcObjectPlacement,l,trsf) + return true; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRectangleProfileDef* l, cgal_face_t& face) { + const double x = l->XDim() / 2.0f * getValue(GV_LENGTH_UNIT); + const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT); + + if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) { + Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity); + return false; + } + + cgal_placement_t trsf2d; + bool has_position = true; +#ifdef USE_IFC4 + has_position = l->hasPosition(); +#endif + if (has_position) { + IfcGeom::CgalKernel::convert(l->Position(), trsf2d); + } + + face = cgal_face_t(); + face.outer.push_back(Kernel::Point_3(-x, -y, 0.0)); + face.outer.push_back(Kernel::Point_3( x, -y, 0.0)); + face.outer.push_back(Kernel::Point_3( x, y, 0.0)); + face.outer.push_back(Kernel::Point_3(-x, y, 0.0)); + + return true; } diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.cpp b/src/ifcgeom/kernels/cgal/CgalEntityMapping.cpp index a5ecf67624..f32a578d27 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.cpp +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.cpp @@ -1,4 +1,4 @@ -/******************************************************************************** +/******************************************************************************** * * * This file is part of IfcOpenShell. * * * @@ -63,7 +63,7 @@ bool IfcGeom::CgalKernel::convert_shape(const IfcBaseClass* l, cgal_shape_t& r) } if ( processed && success ) { - const double precision = getValue(GV_PRECISION); +// const double precision = getValue(GV_PRECISION); // apply_tolerance(r, precision); #ifndef NO_CACHE cache.Shape[id] = r; @@ -77,6 +77,79 @@ bool IfcGeom::CgalKernel::convert_shape(const IfcBaseClass* l, cgal_shape_t& r) return success; } +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcManifoldSolidBrep* l, ConversionResults& shape) { + cgal_shape_t s; + const SurfaceStyle* collective_style = get_style(l); + if (convert_shape(l->Outer(),s) ) { + const SurfaceStyle* indiv_style = get_style(l->Outer()); + + IfcSchema::IfcClosedShell::list::ptr voids(new IfcSchema::IfcClosedShell::list); + if (l->is(IfcSchema::Type::IfcFacetedBrepWithVoids)) { + voids = l->as()->Voids(); + } +#ifdef USE_IFC4 + if (l->is(IfcSchema::Type::IfcAdvancedBrepWithVoids)) { + voids = l->as()->Voids(); + } +#endif + + for (IfcSchema::IfcClosedShell::list::it it = voids->begin(); it != voids->end(); ++it) { +// TopoDS_Shape s2; +// /// @todo No extensive shapefixing since shells should be disjoint. +// /// @todo Awaiting generalized boolean ops module with appropriate checking +// if (convert_shape(l->Outer(), s2)) { +// s = BRepAlgoAPI_Cut(s, s2).Shape(); +// } + } + + shape.push_back(ConversionResult(new CgalShape(s), indiv_style ? indiv_style : collective_style)); + return true; + } + return false; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcConnectedFaceSet* l, cgal_shape_t& shape) { + IfcSchema::IfcFace::list::ptr faces = l->CfsFaces(); + + std::list face_list; + for (IfcSchema::IfcFace::list::it it = faces->begin(); it != faces->end(); ++it) { + bool success = false; + cgal_face_t face; + + try { + success = convert_face(*it, face); + } catch (...) {} + + if (!success) { + Logger::Message(Logger::LOG_WARNING, "Failed to convert face:", (*it)->entity); + continue; + } + +// std::cout << "Face in ConnectedFaceSet: " << std::endl; +// for (auto &point: face.outer) { +// std::cout << "\tPoint(" << point << ")" << std::endl; +// } + + face_list.push_back(face); + } + + // Naive creation + cgal_shape_t polyhedron = CGAL::Polyhedron_3(); + PolyhedronBuilder builder(&face_list); + polyhedron.delegate(builder); + + // Stitch edges +// std::cout << "Before: " << polyhedron.size_of_vertices() << " vertices and " << polyhedron.size_of_facets() << " facets" << std::endl; + CGAL::Polygon_mesh_processing::stitch_borders(polyhedron); + if (!CGAL::Polygon_mesh_processing::is_outward_oriented(polyhedron)) { + CGAL::Polygon_mesh_processing::reverse_face_orientations(polyhedron); + } +// std::cout << "After: " << polyhedron.size_of_vertices() << " vertices and " << polyhedron.size_of_facets() << " facets" << std::endl; + + shape = polyhedron; + return true; +} + bool IfcGeom::CgalKernel::convert_wire(const IfcBaseClass* l, cgal_wire_t& r) { #include "CgalEntityMappingWire.h" Logger::Message(Logger::LOG_ERROR,"No operation defined for:", l); @@ -89,6 +162,94 @@ bool IfcGeom::CgalKernel::convert_face(const IfcBaseClass* l, cgal_face_t& r) { return false; } +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcFace* l, cgal_face_t& face) { + IfcSchema::IfcFaceBound::list::ptr bounds = l->Bounds(); + + int num_outer_bounds = 0; + + for (IfcSchema::IfcFaceBound::list::it it = bounds->begin(); it != bounds->end(); ++it) { + IfcSchema::IfcFaceBound* bound = *it; + if (bound->is(IfcSchema::Type::IfcFaceOuterBound)) num_outer_bounds ++; + } + + if (num_outer_bounds != 1) { + Logger::Message(Logger::LOG_ERROR, "Invalid configuration of boundaries for:", l->entity); + return false; + } + + cgal_face_t mf; + + for (IfcSchema::IfcFaceBound::list::it it = bounds->begin(); it != bounds->end(); ++it) { + IfcSchema::IfcFaceBound* bound = *it; + IfcSchema::IfcLoop* loop = bound->Bound(); + + const bool is_interior = !bound->is(IfcSchema::Type::IfcFaceOuterBound); + + cgal_wire_t wire; + if (!convert_wire(loop, wire)) { + Logger::Message(Logger::LOG_ERROR, "Failed to process face boundary loop", loop->entity); + return false; + } + + if (!is_interior) { + mf.outer = wire; + } else { + mf.inner.push_back(wire); + } + } + + face = mf; + +// std::cout << "Face: " << std::endl; +// for (auto &point: face.outer) { +// std::cout << "\tPoint(" << point << ")" << std::endl; +// } + + return true; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPolyLoop* l, cgal_wire_t& result) { + IfcSchema::IfcCartesianPoint::list::ptr points = l->Polygon(); + + // Parse and store the points in a sequence + cgal_wire_t polygon = std::vector(); + for(IfcSchema::IfcCartesianPoint::list::it it = points->begin(); it != points->end(); ++ it) { + cgal_point_t pnt; + IfcGeom::CgalKernel::convert(*it, pnt); + polygon.push_back(pnt); + } + + // A loop should consist of at least three vertices + std::size_t original_count = polygon.size(); + if (original_count < 3) { + Logger::Message(Logger::LOG_ERROR, "Not enough edges for:", l->entity); + return false; + } + + // TODO: Remove repeated points (and points that are too close to one another?) +// remove_duplicate_points_from_loop(polygon, true); + + std::size_t count = polygon.size(); + if (original_count - count != 0) { + std::stringstream ss; ss << (original_count - count) << " edges removed for:"; + Logger::Message(Logger::LOG_WARNING, ss.str(), l->entity); + } + + if (count < 3) { + Logger::Message(Logger::LOG_ERROR, "Not enough edges for:", l->entity); + return false; + } + + result = polygon; + +// std::cout << "PolyLoop: " << std::endl; +// for (auto &point: polygon) { +// std::cout << "\tPoint(" << point << ")" << std::endl; +// } + + return true; +} + bool IfcGeom::CgalKernel::convert_curve(const IfcBaseClass* l, cgal_curve_t& r) { #include "CgalEntityMappingCurve.h" Logger::Message(Logger::LOG_ERROR,"No operation defined for:", l); diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h index 3908ded811..6cb7f60437 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h @@ -1,4 +1,4 @@ -/******************************************************************************** +/******************************************************************************** * * * This file is part of IfcOpenShell. * * * @@ -28,7 +28,22 @@ #include "../../../ifcparse/IfcParse.h" SHAPES(IfcRepresentation); +// IfcFacetedBrep included +// IfcAdvancedBrep included +// IfcFacetedBrepWithVoids included +// IfcAdvancedBrepWithVoids included +SHAPES(IfcManifoldSolidBrep); SHAPE(IfcExtrudedAreaSolid); +SHAPE(IfcConnectedFaceSet); + +FACE(IfcFace); +FACE(IfcRectangleProfileDef); + +WIRE(IfcPolyLoop); CLASS(IfcCartesianPoint,cgal_point_t); +CLASS(IfcDirection,cgal_direction_t); +CLASS(IfcAxis2Placement2D,cgal_placement_t); +CLASS(IfcAxis2Placement3D,cgal_placement_t); +CLASS(IfcObjectPlacement,cgal_placement_t); diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.h b/src/ifcgeom/kernels/cgal/CgalKernel.h index 3a6be54476..00492f8089 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.h +++ b/src/ifcgeom/kernels/cgal/CgalKernel.h @@ -50,6 +50,49 @@ if ( it != cache.T.end() ) { e = it->second; return true; } #include INCLUDE_SCHEMA(IfcSchema) #undef INCLUDE_SCHEMA +struct PolyhedronBuilder : public CGAL::Modifier_base::HalfedgeDS> { +private: + std::list *face_list; +public: + PolyhedronBuilder(std::list *face_list) { + this->face_list = face_list; + } + + void operator()(CGAL::Polyhedron_3::HalfedgeDS &hds) { + std::list points; + std::list> facet_vertices; + CGAL::Polyhedron_incremental_builder_3::HalfedgeDS> builder(hds, true); + + for (auto &face: *face_list) { + facet_vertices.push_back(std::list()); + for (auto &point: face.outer) { + facet_vertices.back().push_back(points.size()); + points.push_back(point); + } + } + + builder.begin_surface(points.size(), facet_vertices.size()); + + for (auto &point: points) { +// std::cout << "Adding point " << point << std::endl; + builder.add_vertex(point); + } + + for (auto &facet: facet_vertices) { + builder.begin_facet(); +// std::cout << "Adding facet "; + for (auto &vertex: facet) { +// std::cout << vertex << " "; + builder.add_vertex_to_facet(vertex); + } +// std::cout << std::endl; + builder.end_facet(); + } + + builder.end_surface(); + } +}; + namespace IfcGeom { class IFC_GEOM_API CgalCache { diff --git a/src/ifcgeom/schema_agnostic/cgal/CgalConversionResult.cpp b/src/ifcgeom/schema_agnostic/cgal/CgalConversionResult.cpp index 3f98bc00d9..fa1b9a5958 100644 --- a/src/ifcgeom/schema_agnostic/cgal/CgalConversionResult.cpp +++ b/src/ifcgeom/schema_agnostic/cgal/CgalConversionResult.cpp @@ -2,7 +2,47 @@ template void triangulate_helper(const cgal_shape_t, const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation* t, int surface_style_id) { - throw std::runtime_error("Not implemented Triangulate()"); + cgal_shape_t s = shape_; + const cgal_placement_t& trsf = dynamic_cast(place)->trsf(); +// std::cout << "Model: " << s.size_of_facets() << " facets and " << s.size_of_vertices() << " vertices" << std::endl; +// std::cout << "Valid: " << s.is_valid() << std::endl; + + // Apply transformation + if (place != NULL) for (auto &vertex: vertices(s)) { + vertex->point() = vertex->point().transform(trsf); + } + + // Triangulate the shape and compute the normals + std::map vertex_normals; + boost::associative_property_map> vertex_normals_map(vertex_normals); + std::map face_normals; + boost::associative_property_map> face_normals_map(face_normals); + if (CGAL::Polygon_mesh_processing::triangulate_faces(s)) { +// std::cout << "Triangulated model: " << s.size_of_facets() << " facets and " << s.size_of_vertices() << " vertices" << std::endl; + } else { + Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape"); + return; + } + + CGAL::Polygon_mesh_processing::compute_normals(s, vertex_normals_map, face_normals_map); + + // Iterates over the faces of the shape + int num_faces = 0, num_vertices = 0; + for (auto &face: faces(s)) { + CGAL::Polyhedron_3::Halfedge_around_facet_const_circulator current_halfedge = face->facet_begin(); + do { + t->addVertex(surface_style_id, + CGAL::to_double(current_halfedge->vertex()->point().cartesian(0)), + CGAL::to_double(current_halfedge->vertex()->point().cartesian(1)), + CGAL::to_double(current_halfedge->vertex()->point().cartesian(2))); + for (int i = 0; i < 3; ++i) t->normals().push_back(CGAL::to_double(face_normals_map[face].cartesian(i))); + t->faces().push_back(num_vertices); + ++num_vertices; + ++current_halfedge; + } while (current_halfedge != face->facet_begin()); + t->material_ids().push_back(surface_style_id); + ++num_faces; + } } void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const { diff --git a/src/ifcgeom/schema_agnostic/cgal/CgalConversionResult.h b/src/ifcgeom/schema_agnostic/cgal/CgalConversionResult.h index 9bb534437f..59c4e63e59 100644 --- a/src/ifcgeom/schema_agnostic/cgal/CgalConversionResult.h +++ b/src/ifcgeom/schema_agnostic/cgal/CgalConversionResult.h @@ -20,12 +20,31 @@ #ifndef CGALCONVERSIONRESULT_H #define CGALCONVERSIONRESULT_H -typedef void* cgal_shape_t; -typedef void* cgal_face_t; -typedef void* cgal_wire_t; -typedef void* cgal_curve_t; -typedef void* cgal_placement_t; -typedef void* cgal_point_t; +#include +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; + +typedef Kernel::Aff_transformation_3 cgal_placement_t; +typedef Kernel::Point_3 cgal_point_t; +typedef Kernel::Vector_3 cgal_direction_t; +typedef std::vector cgal_curve_t; +typedef std::vector cgal_wire_t; + +struct cgal_face_t { + cgal_wire_t outer; + std::vector inner; +}; + +typedef CGAL::Polyhedron_3 cgal_shape_t; +typedef boost::graph_traits>::vertex_descriptor cgal_vertex_descriptor_t; +typedef boost::graph_traits>::face_descriptor cgal_face_descriptor_t; #include "../../../ifcgeom/schema_agnostic/ConversionResult.h" @@ -41,18 +60,19 @@ namespace IfcGeom { operator const cgal_placement_t& () { return trsf_; } virtual double Value(int i, int j) const { - // Get cell from placement as 4x3 matrix as implemented in OCCT. We'll have to check exact semantics. - throw std::runtime_error("Not implemented"); + // TODO: Check +// std::cout << "Getting CgalPlacement with i = " << i << " and j = " << j << std::endl; + return CGAL::to_double(trsf_.cartesian(i-1, j-1)); } virtual void Multiply(const ConversionResultPlacement* other) { - // Multiply matrix as implemented in OCCT. We'll have to check exact semantics. - throw std::runtime_error("Not implemented"); + // TODO: Check + trsf_ = ((CgalPlacement *)other)->trsf_ * trsf_; } virtual void PreMultiply(const ConversionResultPlacement* other) { - // PreMultiply matrix as implemented in OCCT. We'll have to check exact semantics. - throw std::runtime_error("Not implemented"); + // TODO: Check + trsf_ = trsf_ * ((CgalPlacement *)other)->trsf_; } virtual ConversionResultPlacement* clone() const { @@ -73,7 +93,7 @@ namespace IfcGeom { private: cgal_placement_t trsf_; }; - + class CgalShape : public ConversionResultShape { public: CgalShape(const cgal_shape_t& shape) @@ -104,4 +124,4 @@ namespace IfcGeom { } -#endif \ No newline at end of file +#endif