/* * Copyright (c) 1991-2020 by STEP Tools Inc. * All Rights Reserved * * This software is furnished under a license and may be used and * copied only in accordance with the terms of such license and with * the inclusion of the above copyright notice. This software and * accompanying written materials or any other copies thereof may * not be provided or otherwise made available to any other person. * No title to or ownership of the software is hereby transferred. * * Author: Jochen Fritz (jfritz@steptools.com) */ // Sample program to facet all shapes in file #include #include // When this flag is 0, the print_mesh_details() function only prints // some summary information about each mesh. When set to 1, it will // call print_triangle() to print the coordinates of each triangle, // which produces a large amount of output! // int PRINT_ALL_TRIANGLES = 0; void print_product (IfcProduct * p); void print_shape ( IfcRepresentation * rep, RoseXform &xform ); void print_mesh_details ( const RoseMesh * mesh, RoseXform &mesh_xform, IfcRepresentationItem * solid, const char * pfx ); void print_triangle ( const RoseMesh * fs, RoseXform &xform, unsigned facet_num, const char * pfx ); void print_transform ( RoseXform &xf, const char * pfx ); int main (int /*argc*/, char ** /*argv*/) { ifclib_init(); // initialize merged cad library const char * srcfile = "Duplex_Electrical_20121207.ifc"; // uncomment to take args from the command line instead // if (argc < 2) usage(argv[0]); // srcfile = argv[1]; RoseDesign * d = ROSE.findDesign(srcfile); if (!d) { printf ("Could not open IFC file %s\n", srcfile); exit (1); } RoseMeshWorkerContext context; RoseMeshOptions facet_opts; context.setFacetOptions(&facet_opts); // create meshes for everything in the design ifcmesh_worker_render_design(d, &context); rose_mesh_worker_wait_all(); // Walk the product tree and print the meshes RoseCursor objs; RoseObject * obj; rose_mark_begin(); objs.traverse(d); objs.domain(ROSE_DOMAIN(IfcProduct)); while ((obj=objs.next()) != 0) { print_product (ROSE_CAST(IfcProduct,obj)); } rose_mark_end(); return 0; } void print_product (IfcProduct * p) { unsigned i,sz; IfcProductRepresentation * pr = p->Representation(); ListOfIfcRepresentation * reps = pr? pr->Representations(): 0; RoseXform xform; ifcmesh_xform_put(xform, p->ObjectPlacement()); const char * name = (p->Name()? p->Name() : ""); const char * guid = (p->GlobalId()? p->GlobalId(): ""); printf ("\n----------\n"); printf ("PRODUCT #%lu: %s [%s]\n", p-> entity_id(), name, guid); if (!reps) { printf (" => NO SHAPES\n"); return; } print_transform (xform, ""); for (i=0, sz=reps->size(); iget(i), xform); } void print_shape ( IfcRepresentation * rep, RoseXform &xform ) { if (!rep) return; if (rose_is_marked(rep)) { printf (" SHAPE REP #%lu: already printed\n", rep-> entity_id()); return; } rose_mark_set(rep); unsigned i,sz; SetOfIfcRepresentationItem * items = rep->Items(); for (i=0, sz=items->size(); iget(i); if (!it) continue; if (it->isa(ROSE_DOMAIN(IfcMappedItem))) { // embedded shape from an assembly IfcMappedItem * mi = ROSE_CAST(IfcMappedItem, it); IfcRepresentationMap * source = mi->MappingSource(); if (!source) continue; print_shape(source->MappedRepresentation(), xform); continue; } // does this have a mesh? const IFCMesh * mesh = ifcmesh_find_shell(rep, it); if (mesh) { if (rose_is_marked(it)) { printf ("Shell already processed: #%lu\n", it->entity_id()); continue; } rose_mark_set(it); printf (" SHAPE REP #%lu:\n", rep-> entity_id()); print_mesh_details(mesh, xform, it, "\t"); } } } void print_mesh_details ( const RoseMesh * mesh, RoseXform &mesh_xform, IfcRepresentationItem * solid, const char * pfx ) { fputs (pfx, stdout); printf ("Solid #%lu (%s)\n", solid-> entity_id(), solid-> domain()-> name() ); if (!mesh) { fputs (pfx, stdout); printf (" -- no mesh --\n"); } else { fputs (pfx, stdout); printf ( "mesh has %u triangles\n", mesh-> getFacetCount() ); // Print all of the triangles - Flip the flag below if you // want this. It produces a large amount of output! // if (PRINT_ALL_TRIANGLES) { unsigned i, sz; for (i=0, sz=mesh->getFacetCount(); i< sz; i++) print_triangle (mesh, mesh_xform, i, pfx); } } } void print_triangle ( const RoseMesh * fs, RoseXform &xform, unsigned facet_num, const char * pfx ) { double v[3]; double n[3]; const RoseMeshFacet * f = fs-> getFacet(facet_num); fputs (pfx, stdout); printf("facet %u\n", facet_num); if (!f) return; // The components of the triangle verticies and vertex normals are // given by an index into internal tables. Apply the transform so // that the coordinates and directions are placed correctly. rose_xform_apply (v, xform, fs-> getVertex(f-> verts[0])); rose_xform_apply_dir (n, xform, fs-> getNormal(f-> normals[0])); fputs (pfx, stdout); printf("v1: (%.6g %.6g %.6g)\t", v[0], v[1], v[2]); printf("n1: (%.3f %.3f %.3f)\n", n[0], n[1], n[2]); rose_xform_apply (v, xform, fs-> getVertex(f-> verts[1])); rose_xform_apply_dir (n, xform, fs-> getNormal(f-> normals[1])); fputs (pfx, stdout); printf("v2: (%.6g %.6g %.6g)\t", v[0], v[1], v[2]); printf("n2: (%.3f %.3f %.3f)\n", n[0], n[1], n[2]); rose_xform_apply (v, xform, fs-> getVertex(f-> verts[2])); rose_xform_apply_dir (n, xform, fs-> getNormal(f-> normals[2])); fputs (pfx, stdout); printf("v3: (%.6g %.6g %.6g)\t", v[0], v[1], v[2]); printf("n3: (%.3f %.3f %.3f)\n", n[0], n[1], n[2]); } void print_transform ( RoseXform &xf, const char * pfx ) { fputs (pfx, stdout); printf("Loc: (%.6g %.6g %.6g)\n", xf.origin().x(), xf.origin().y(), xf.origin().z()); fputs (pfx, stdout); printf("zdir (%.3f %.3f %.3f)\n", xf.zdir().i(), xf.zdir().j(), xf.zdir().k()); fputs (pfx, stdout); printf("xdir (%.3f %.3f %.3f)\n", xf.xdir().i(), xf.xdir().j(), xf.xdir().k()); }