diff --git a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp index 10b2bc49ec..1a488a274a 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp @@ -49,6 +49,25 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcDirection* l, cgal_directi 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; @@ -60,9 +79,10 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcAxis2Placement3D* l, cgal_ if ( hasRef ) IfcGeom::CgalKernel::convert(l->RefDirection(),refDirection); // TODO: From Thomas' email. Should be checked. - trsf = Kernel::Aff_transformation_3(refDirection.cartesian(0), axis.cartesian(0)*refDirection.cartesian(0), axis.cartesian(0), o.cartesian(0), - refDirection.cartesian(1), axis.cartesian(1)*refDirection.cartesian(1), axis.cartesian(1), o.cartesian(1), - refDirection.cartesian(2), axis.cartesian(2)*refDirection.cartesian(2), axis.cartesian(2), o.cartesian(2)); + 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)); // CACHE(IfcAxis2Placement3D,l,trsf) return true; diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp index 81fd474622..529e692abb 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp @@ -5,6 +5,11 @@ void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings, cgal_shape_t s = shape_; const cgal_placement_t& trsf = dynamic_cast(place)->trsf(); + // Apply transformation + 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); @@ -23,7 +28,6 @@ void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings, // Iterates over the faces of the shape int num_faces = 0, num_vertices = 0; -// TopExp_Explorer exp; for (auto &face: faces(s)) { CGAL::Polyhedron_3::Halfedge_around_facet_const_circulator current_halfedge = face->facet_begin(); do { @@ -32,152 +36,11 @@ void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings, 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); +// t->faces().push_back(num_vertices); ++num_vertices; ++current_halfedge; } while (current_halfedge != face->facet_begin()); - t->material_ids().push_back(surface_style_id); +// t->material_ids().push_back(surface_style_id); ++num_faces; - -// TopLoc_Location loc; -// Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face, loc); -// -// if (!tri.IsNull()) { -// -// // A 3x3 matrix to rotate the vertex normals -// const gp_Mat rotation_matrix = trsf.VectorialPart(); -// -// // Keep track of the number of times an edge is used -// // Manifold edges (i.e. edges used twice) are deemed invisible -// std::map, int> edgecount; -// std::vector > edges_temp; -// -// const TColgp_Array1OfPnt& nodes = tri->Nodes(); -// const TColgp_Array1OfPnt2d& uvs = tri->UVNodes(); -// std::vector coords; -// BRepGProp_Face prop(face); -// std::map dict; -// -// // Vertex normals are only calculated if vertices are not welded and calculation is not disable explicitly. -// const bool calculate_normals = !settings.get(IteratorSettings::WELD_VERTICES) && -// !settings.get(IteratorSettings::NO_NORMALS); -// -// for (int i = 1; i <= nodes.Length(); ++i) { -// coords.push_back(nodes(i).Transformed(loc).XYZ()); -// trsf.Transforms(*coords.rbegin()); -// const gp_XYZ& last = *coords.rbegin(); -// dict[i] = t->addVertex(surface_style_id, last.X(), last.Y(), last.Z()); -// -// if (calculate_normals) { -// const gp_Pnt2d& uv = uvs(i); -// gp_Pnt p; -// gp_Vec normal_direction; -// prop.Normal(uv.X(), uv.Y(), p, normal_direction); -// gp_Vec normal(0., 0., 0.); -// if (normal_direction.Magnitude() > ALMOST_ZERO) { -// normal = gp_Dir(normal_direction.XYZ() * rotation_matrix); -// } -// t->normals().push_back(static_cast(normal.X())); -// t->normals().push_back(static_cast(normal.Y())); -// t->normals().push_back(static_cast(normal.Z())); -// } -// } -// -// const Poly_Array1OfTriangle& triangles = tri->Triangles(); -// for (int i = 1; i <= triangles.Length(); ++i) { -// int n1, n2, n3; -// if (face.Orientation() == TopAbs_REVERSED) -// triangles(i).Get(n3, n2, n1); -// else triangles(i).Get(n1, n2, n3); -// -// t->faces().push_back(dict[n1]); -// t->faces().push_back(dict[n2]); -// t->faces().push_back(dict[n3]); -// -// t->material_ids().push_back(surface_style_id); -// -// t->addEdge(dict[n1], dict[n2], edgecount, edges_temp); -// t->addEdge(dict[n2], dict[n3], edgecount, edges_temp); -// t->addEdge(dict[n3], dict[n1], edgecount, edges_temp); -// } -// for (std::vector >::const_iterator jt = edges_temp.begin(); jt != edges_temp.end(); ++jt) { -// if (edgecount[*jt] == 1) { -// // non manifold edge, face boundary -// t->edges().push_back(jt->first); -// t->edges().push_back(jt->second); -// } -// } -// } } -// -// if (num_faces == 0) { -// // Edges are only emitted if there are no faces. A mixed representation of faces -// // and loose edges is discouraged by the standard. An alternative would be to use -// // TopExp_Explorer texp(s, TopAbs_EDGE, TopAbs_FACE) to find edges that do not -// // belong to any face. -// for (TopExp_Explorer texp(s, TopAbs_EDGE); texp.More(); texp.Next()) { -// BRepAdaptor_Curve crv(TopoDS::Edge(texp.Current())); -// GCPnts_QuasiUniformDeflection tessellater(crv, settings.deflection_tolerance()); -// int n = tessellater.NbPoints(); -// int start = (int)t->verts().size() / 3; -// for (int i = 1; i <= n; ++i) { -// gp_XYZ p = tessellater.Value(i).XYZ(); -// -// /* -// // In case you want direction arrows on your edges -// double u = tessellater.Parameter(i); -// gp_XYZ p2, p3; -// gp_Pnt tmp; -// gp_Vec tmp2; -// crv.D1(u, tmp, tmp2); -// gp_Dir d1, d2, d3, d4; -// d1 = tmp2; -// if (texp.Current().Orientation() == TopAbs_REVERSED) { -// d1 = -d1; -// } -// if (fabs(d1.Z()) < 0.5) { -// d2 = d1.Crossed(gp::DZ()); -// } else { -// d2 = d1.Crossed(gp::DY()); -// } -// d3 = d1.XYZ() + d2.XYZ(); -// d4 = d1.XYZ() - d2.XYZ(); -// p2 = p - d3.XYZ() / 10.; -// p3 = p - d4.XYZ() / 10.; -// trsf.Transforms(p2); -// trsf.Transforms(p3); -// _material_ids.push_back(surface_style_id); -// _material_ids.push_back(surface_style_id); -// _verts.push_back(static_cast

(p2.X())); -// _verts.push_back(static_cast

(p2.Y())); -// _verts.push_back(static_cast

(p2.Z())); -// _verts.push_back(static_cast

(p3.X())); -// _verts.push_back(static_cast

(p3.Y())); -// _verts.push_back(static_cast

(p3.Z())); -// */ -// -// trsf.Transforms(p); -// -// t->material_ids().push_back(surface_style_id); -// -// t->verts().push_back(static_cast(p.X())); -// t->verts().push_back(static_cast(p.Y())); -// t->verts().push_back(static_cast(p.Z())); -// -// if (i > 1) { -// t->edges().push_back(start + i - 2); -// t->edges().push_back(start + i - 1); -// // _edges.push_back(start + 3 * (i - 2) + 2); -// // _edges.push_back(start + 3 * (i - 1) + 2); -// } -// -// // _edges.push_back(start + 3 * (i - 1) + 0); -// // _edges.push_back(start + 3 * (i - 1) + 2); -// // _edges.push_back(start + 3 * (i - 1) + 1); -// // _edges.push_back(start + 3 * (i - 1) + 2); -// } -// } -// } -// -// BRepTools::Clean(s); } diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.h b/src/ifcgeom/kernels/cgal/CgalConversionResult.h index b20c8c8858..6a6e6157e8 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.h +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.h @@ -1,4 +1,4 @@ -/******************************************************************************** +/******************************************************************************** * * * This file is part of IfcOpenShell. * * * @@ -34,15 +34,17 @@ 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. + // TODO: Check return CGAL::to_double(trsf_.cartesian(i, j)); } virtual void Multiply(const ConversionResultPlacement* other) { - // Multiply matrix as implemented in OCCT. We'll have to check exact semantics. + // TODO: Check + trsf_ = ((CgalPlacement *)other)->trsf_ * trsf_; throw std::runtime_error("Not implemented"); } virtual void PreMultiply(const ConversionResultPlacement* other) { - // PreMultiply matrix as implemented in OCCT. We'll have to check exact semantics. + // TODO: Check + trsf_ = trsf_ * ((CgalPlacement *)other)->trsf_; throw std::runtime_error("Not implemented"); } virtual ConversionResultPlacement* clone() const { diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h index a3c68c56ea..ddfab3fc5a 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h @@ -44,6 +44,6 @@ WIRE(IfcPolyLoop); CLASS(IfcCartesianPoint,cgal_point_t); CLASS(IfcDirection,cgal_direction_t); -//CLASS(IfcAxis2Placement2D,cgal_placement_t); +CLASS(IfcAxis2Placement2D,cgal_placement_t); CLASS(IfcAxis2Placement3D,cgal_placement_t); CLASS(IfcObjectPlacement,cgal_placement_t);