/* * Copyright (c) 1991-2020 by STEP Tools Inc. * All Rights Reserved. * * Permission to use, copy, modify, and distribute this software and * its documentation is hereby granted, provided that this copyright * notice and license appear on all copies of the software. * * STEP TOOLS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. STEP TOOLS * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. * * Author: David Loffredo (loffredo@steptools.com) */ // Sample program to facet step assembly #include #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; static void print_mesh_for_product ( stp_product_definition * pd ); static void print_mesh_for_shape ( stp_representation * rep, RoseXform &xform, RoseObject * rep_rel_or_mapped_item, stp_product_definition * pd, // null if not a new product unsigned nest_depth // for indenting ); static void print_mesh_details ( const RoseMesh * mesh, RoseXform &xform, stp_representation_item * solid, const char * pfx ); static void print_triangle ( const RoseMesh * fs, RoseXform &xform, unsigned facet_num, const char * pfx ); static void print_transform ( RoseXform &xform, const char * pfx ); int main (int argc, char ** argv) { ROSE.quiet(1); stplib_init(); // initialize step aim library stixmesh_init(); const char * srcfile = "as1-ac-214.stp"; RoseDesign * d = ROSE.findDesign(srcfile); if (!d) { printf ("Could not open STEP file %s\n", srcfile); exit (1); } // prepare for working with assemblies rose_compute_backptrs(d); stix_tag_asms(d); // start the worker threads rendering in parallel, then wait for // them to finish. RoseMeshWorkerContext context; RoseMeshOptions facet_opts; context.setFacetOptions(&facet_opts); stixmesh_worker_render_design(d, &context); rose_mesh_worker_wait_all(); // Navigate the shape tree of the assembly to each shape in // context with its assembly placement. Print the mesh details // and placement info. // unsigned i,sz; StpAsmProductDefVec roots; stix_find_root_products (&roots, d); for (i=0, sz=roots.size(); i formation(); stp_product * p = pdf? pdf-> of_product(): 0; const char * pname = p? p-> name(): 0; if (!pname || !*pname) pname = "[no name]"; printf ("ROOT PRODUCT #%lu - %s\n", pd-> entity_id(), pname); for (i=0, sz=pm->shapes.size(); i0) { printf ("------------------------------\n"); printf ("Alternate shape tree #%u for ROOT PRODUCT #%lu - %s\n", i, pd-> entity_id(), pname); } // The root placement is usually the identity matrix but some // systems put a standalone AP3D at the top to place the whole // thing in the global space. RoseXform starting_placement; stp_shape_representation * rep = pm->shapes[i]; StixMgrAsmShapeRep * rep_mgr = StixMgrAsmShapeRep::find(rep); if (rep_mgr && rep_mgr->root_placement) { stix_xform_put(starting_placement, rep_mgr->root_placement); printf ("Using Custom Coordinate System defined by #%lu\n", rep_mgr->root_placement-> entity_id()); } print_mesh_for_shape (rep, starting_placement, 0, 0, 0); } } void print_mesh_for_shape ( stp_representation * rep, RoseXform &rep_xform, RoseObject * rep_rel_or_mapped_item, stp_product_definition * pd, // null if not a new product unsigned nest_depth // for indenting ) { unsigned i, sz; RoseStringObject nest_indent = ""; if (!rep) return; // indent for a nice tree printout if (pd) nest_depth++; for (i=0; i formation(); stp_product * p = pdf? pdf-> of_product(): 0; const char * pname = p? p-> name(): 0; if (!pname || !*pname) pname = "[no name]"; fputs (nest_indent.as_const(), stdout); fputs ("--------------------\n", stdout); fputs (nest_indent.as_const(), stdout); printf ("PRODUCT #%lu - %s\n", pd-> entity_id(), pname); } // Does the rep have any meshed items? In an assembly, some reps // just contain placements for transforming components. If there // are solids, we should have previously generated meshes. // fputs ("\n", stdout); fputs (nest_indent.as_const(), stdout); printf ("Shape #%lu (%s)\n", rep-> entity_id(), rep-> domain()-> name()); fputs (nest_indent.as_const(), stdout); printf ("placement -- \n"); print_transform (rep_xform, nest_indent.as_const()); SetOfstp_representation_item * items = rep->items(); unsigned solids_printed = 0; for (i=0, sz=items->size(); iget(i); StixMeshBuilder * mb = stixmesh_worker_find_builder (rep, it); if (mb) { print_mesh_details ( mb->getStpMesh(), rep_xform, it, nest_indent.as_const() ); solids_printed++; } } if (!solids_printed) { fputs (nest_indent.as_const(), stdout); printf (" -- no meshes in representation --\n"); } // Go through all of the child shapes which can be attached by a // shape_reprepresentation_relationship or a mapped_item. If the // relation has a NAUO associated with it, then it is the start of // a different product, otherwise it is still part of the shape of // this one. // StixMgrAsmShapeRep * rep_mgr = StixMgrAsmShapeRep::find(rep); if (!rep_mgr) return; for (i=0, sz=rep_mgr->child_rels.size(); ichild_rels[i]; stp_representation * child = stix_get_shape_usage_child_rep (rel); stp_product_definition * cpd = stix_get_shape_usage_child_product (rel); // Move to location in enclosing asm RoseXform child_xform = stix_get_shape_usage_xform (rel); rose_xform_compose(child_xform, rep_xform, child_xform); print_mesh_for_shape (child, child_xform, rel, cpd, nest_depth); } for (i=0, sz=rep_mgr->child_mapped_items.size(); ichild_mapped_items[i]; stp_representation * child = stix_get_shape_usage_child_rep (rel); stp_product_definition * cpd = stix_get_shape_usage_child_product (rel); // Move to location in enclosing asm RoseXform child_xform = stix_get_shape_usage_xform (rel); rose_xform_compose(child_xform, rep_xform, child_xform); print_mesh_for_shape (child, child_xform, rel, cpd, nest_depth); } } void print_mesh_details ( const RoseMesh * mesh, RoseXform &mesh_xform, stp_representation_item * solid, const char * pfx ) { fputs ("\n", stdout); 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() ); fputs (pfx, stdout); printf ( "step faces: %u , step edges: %u\n", mesh-> getFaceCount(), mesh-> getEdgeCount() ); fputs (pfx, stdout); printf ( "step global uncertainty: %g\n", mesh-> getGlobalUncertainty() ); // 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()); }