int brep_build_bvh(struct brep_specific* bs, struct rt_brep_internal* bi) { ON_TextLog tl(stderr); ON_Brep* brep = bs->brep; if (brep == NULL || !brep->IsValid(&tl)) { bu_log("brep is NOT valid"); return -1; } bs->bvh = new BBNode(brep->BoundingBox()); // need to extract faces, and build bounding boxes for each face, // then combine the face BBs back up, combining them together to // better split the hierarchy std::list<SurfaceTree*> surface_trees; ON_BrepFaceArray& faces = brep->m_F; for (int i = 0; i < faces.Count(); i++) { TRACE1("Face: " << i); ON_BrepFace& face = faces[i]; SurfaceTree* st = new SurfaceTree(&face); face.m_face_user.p = st; brep_preprocess_trims(face, st); // add the surface bounding volumes to a list, so we can build // down a hierarchy from the brep bounding volume surface_trees.push_back(st); } brep_bvh_subdivide(bs->bvh, surface_trees); return 0; }
bool STEPWrapper::convert(BRLCADWrapper *dot_g) { MAP_OF_PRODUCT_NAME_TO_ENTITY_ID name2id_map; MAP_OF_ENTITY_ID_TO_PRODUCT_NAME id2name_map; MAP_OF_ENTITY_ID_TO_PRODUCT_ID id2productid_map; MAP_OF_PRODUCT_NAME_TO_ENTITY_ID::iterator niter = name2id_map.end(); if (!dot_g) { return false; } this->dotg = dot_g; int num_ents = instance_list->InstanceCount(); for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_shape_definition_representation))) { ShapeDefinitionRepresentation *sdr = dynamic_cast<ShapeDefinitionRepresentation *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (!sdr) { bu_exit(1, "ERROR: unable to allocate a 'ShapeDefinitionRepresentation' entity\n"); } else { int sdr_id = sdr->GetId(); std::string pname = sdr->GetProductName(); int product_id = sdr->GetProductId(); id2productid_map[sdr_id] = product_id; if (pname.empty()) { std::string str = "ShapeDefinitionRepresentation@"; str = dotg->GetBRLCADName(str); id2name_map[sdr_id] = pname; } else { std::string temp = pname; int index = 2; while ((niter=name2id_map.find(temp)) != name2id_map.end()) { temp = pname + "_" + static_cast<ostringstream*>( &(ostringstream() << (index++)) )->str(); } pname = temp; if ((niter=name2id_map.find(pname)) == name2id_map.end()) { id2name_map[sdr_id] = pname; name2id_map[pname] = product_id; id2name_map[product_id] = pname; } } AdvancedBrepShapeRepresentation *aBrep = sdr->GetAdvancedBrepShapeRepresentation(); if (aBrep) { if (pname.empty()) { std::string str = "product@"; pname = dotg->GetBRLCADName(str); id2name_map[aBrep->GetId()] = pname; id2name_map[product_id] = pname; } else { id2name_map[aBrep->GetId()] = pname; id2name_map[product_id] = pname; } id2productid_map[aBrep->GetId()] = product_id; if (Verbose()) { if (!pname.empty()) { std::cerr << std::endl << " Generating Product -" << pname ; } else { std::cerr << std::endl << " Generating Product"; } } LocalUnits::length = aBrep->GetLengthConversionFactor(); LocalUnits::planeangle = aBrep->GetPlaneAngleConversionFactor(); LocalUnits::solidangle = aBrep->GetSolidAngleConversionFactor(); ON_Brep *onBrep = aBrep->GetONBrep(); if (!onBrep) { delete sdr; bu_exit(1, "ERROR: failure creating advanced boundary representation from %s\n", stepfile.c_str()); } else { ON_TextLog tl; if (!onBrep->IsValid(&tl)) { bu_log("WARNING: %s is not valid\n", name.c_str()); } //onBrep->SpSplitClosedFaces(); //ON_Brep *tbrep = TightenBrep(onBrep); mat_t mat; MAT_IDN(mat); Axis2Placement3D *axis = aBrep->GetAxis2Placement3d(); if (axis != NULL) { //assign matrix values double translate_to[3]; const double *toXaxis = axis->GetXAxis(); const double *toYaxis = axis->GetYAxis(); const double *toZaxis = axis->GetZAxis(); mat_t rot_mat; VMOVE(translate_to,axis->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); MAT_IDN(rot_mat); VMOVE(&rot_mat[0], toXaxis); VMOVE(&rot_mat[4], toYaxis); VMOVE(&rot_mat[8], toZaxis); bn_mat_inv(mat, rot_mat); MAT_DELTAS_VEC(mat, translate_to); } dotg->WriteBrep(pname, onBrep,mat); delete onBrep; } } else { // must be an assembly if (pname.empty()) { std::string str = "assembly@"; pname = dotg->GetBRLCADName(str); } ShapeRepresentation *aSR = sdr->GetShapeRepresentation(); if (aSR) { int sr_id = aSR->GetId(); id2name_map[sr_id] = pname; id2name_map[product_id] = pname; id2productid_map[sr_id] = product_id; } } Factory::DeleteObjects(); } } } /* * Pickup BREP related to SHAPE_REPRESENTATION through SHAPE_REPRESENTATION_RELATIONSHIP * * like the following found in OpenBook Part 'C': * #21281=SHAPE_DEFINITION_REPRESENTATION(#21280,#21270); * #21280=PRODUCT_DEFINITION_SHAPE('','SHAPE FOR C.',#21279); * #21279=PRODUCT_DEFINITION('design','',#21278,#21275); * #21278=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('1','LAST_VERSION',#21277,.MADE.); * #21277=PRODUCT('C','C','NOT SPECIFIED',(#21276)); * #21270=SHAPE_REPRESENTATION('',(#21259),#21267); * #21259=AXIS2_PLACEMENT_3D('DANTE_BX_CPU_TOP_1',#21256,#21257,#21258); * #21267=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#21266)) * GLOBAL_UNIT_ASSIGNED_CONTEXT((#21260,#21264,#21265))REPRESENTATION_CONTEXT('ID1','3')); * * #21271=SHAPE_REPRESENTATION_RELATIONSHIP('','',#21270,#21268); * #21268=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#21254),#21267); * #21272=SHAPE_REPRESENTATION_RELATIONSHIP('','',#21270,#21269); * #21269=MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#21255),#21267); * */ for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_shape_representation_relationship))) { ShapeRepresentationRelationship *srr = dynamic_cast<ShapeRepresentationRelationship *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (srr) { ShapeRepresentation *aSR = dynamic_cast<ShapeRepresentation *>(srr->GetRepresentationRelationshipRep_1()); AdvancedBrepShapeRepresentation *aBrep = dynamic_cast<AdvancedBrepShapeRepresentation *>(srr->GetRepresentationRelationshipRep_2()); if (!aBrep) { //try rep_1 aBrep = dynamic_cast<AdvancedBrepShapeRepresentation *>(srr->GetRepresentationRelationshipRep_1()); aSR = dynamic_cast<ShapeRepresentation *>(srr->GetRepresentationRelationshipRep_2()); } if ((aSR) && (aBrep)) { int sr_id = aSR->GetId(); MAP_OF_ENTITY_ID_TO_PRODUCT_ID::iterator it = id2productid_map.find(sr_id); if (it != id2productid_map.end()) { // product found int product_id = (*it).second; int brep_id = aBrep->GetId(); it = id2productid_map.find(brep_id); if (it == id2productid_map.end()) { // brep not loaded yet so lets do that here. string pname = id2name_map[product_id]; id2productid_map[brep_id] = product_id; if (Verbose()) { if (!pname.empty()) { std::cerr << std::endl << " Generating Product -" << pname ; } else { std::cerr << std::endl << " Generating Product"; } } LocalUnits::length = aBrep->GetLengthConversionFactor(); LocalUnits::planeangle = aBrep->GetPlaneAngleConversionFactor(); LocalUnits::solidangle = aBrep->GetSolidAngleConversionFactor(); ON_Brep *onBrep = aBrep->GetONBrep(); if (!onBrep) { bu_exit(1, "ERROR: failure creating advanced boundary representation from %s\n", stepfile.c_str()); } else { ON_TextLog tl; if (!onBrep->IsValid(&tl)) { bu_log("WARNING: %s is not valid\n", name.c_str()); } //onBrep->SpSplitClosedFaces(); //ON_Brep *tbrep = TightenBrep(onBrep); mat_t mat; MAT_IDN(mat); Axis2Placement3D *axis = aBrep->GetAxis2Placement3d(); if (axis != NULL) { //assign matrix values double translate_to[3]; const double *toXaxis = axis->GetXAxis(); const double *toYaxis = axis->GetYAxis(); const double *toZaxis = axis->GetZAxis(); mat_t rot_mat; VMOVE(translate_to,axis->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); MAT_IDN(rot_mat); VMOVE(&rot_mat[0], toXaxis); VMOVE(&rot_mat[4], toYaxis); VMOVE(&rot_mat[8], toZaxis); bn_mat_inv(mat, rot_mat); MAT_DELTAS_VEC(mat, translate_to); } dotg->WriteBrep(pname, onBrep,mat); delete onBrep; } } } } Factory::DeleteObjects(); } } } if (Verbose()) { std::cerr << std::endl << " Generating BRL-CAD hierarchy." << std::endl; } for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_context_dependent_shape_representation))) { ContextDependentShapeRepresentation *aCDSR = dynamic_cast<ContextDependentShapeRepresentation *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (aCDSR) { int rep_1_id = aCDSR->GetRepresentationRelationshipRep_1()->GetId(); int rep_2_id = aCDSR->GetRepresentationRelationshipRep_2()->GetId(); int pid_1 = id2productid_map[rep_1_id]; int pid_2 = id2productid_map[rep_2_id]; Axis2Placement3D *axis1 = NULL; Axis2Placement3D *axis2 = NULL; if ((id2name_map.find(rep_1_id) != id2name_map.end()) && (id2name_map.find(rep_2_id) != id2name_map.end())) { string comb = id2name_map[rep_1_id]; string member = id2name_map[rep_2_id]; mat_t mat; MAT_IDN(mat); ProductDefinition *relatingProduct = aCDSR->GetRelatingProductDefinition(); ProductDefinition *relatedProduct = aCDSR->GetRelatedProductDefinition(); if (relatingProduct && relatedProduct) { string relatingName = relatingProduct->GetProductName(); int relatingID = relatingProduct->GetProductId(); string relatedName = relatedProduct->GetProductName(); int relatedID = relatedProduct->GetProductId(); if ((relatingID == pid_1) && (relatedID == pid_2)) { axis1 = aCDSR->GetTransformItem_1(); axis2 = aCDSR->GetTransformItem_2(); comb = id2name_map[rep_1_id]; member = id2name_map[rep_2_id]; } else if ((relatingID == pid_2) && (relatedID == pid_1)) { axis1 = aCDSR->GetTransformItem_2(); axis2 = aCDSR->GetTransformItem_1(); comb = id2name_map[rep_2_id]; member = id2name_map[rep_1_id]; } else { std::cerr << "Error: Found Representation Relationship Rep_1(name=" << comb << ",Id=" << rep_1_id << ")" << std::endl; std::cerr << "Error: Found Representation Relationship Rep_2(name=" << member << ",Id=" << rep_2_id << ")" << std::endl; std::cerr << "Error: but Relating ProductDefinition (name=" << relatingName << ",Id=" << relatingID << ")" << std::endl; std::cerr << "Error: Related ProductDefinition (name=" << relatedName << ",Id=" << relatedID << ")" << std::endl; } } if ((axis1 != NULL) && (axis2 != NULL)) { mat_t to_mat; mat_t from_mat; mat_t toinv_mat; //assign matrix values double translate_to[3]; double translate_from[3]; const double *toXaxis = axis1->GetXAxis(); const double *toYaxis = axis1->GetYAxis(); const double *toZaxis = axis1->GetZAxis(); const double *fromXaxis = axis2->GetXAxis(); const double *fromYaxis = axis2->GetYAxis(); const double *fromZaxis = axis2->GetZAxis(); VMOVE(translate_to,axis1->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); VMOVE(translate_from,axis2->GetOrigin()); VSCALE(translate_from,translate_from,-LocalUnits::length); // undo from trans/rot MAT_IDN(from_mat); VMOVE(&from_mat[0], fromXaxis); VMOVE(&from_mat[4], fromYaxis); VMOVE(&from_mat[8], fromZaxis); MAT_DELTAS_VEC(from_mat, translate_from); // do to trans/rot MAT_IDN(to_mat); VMOVE(&to_mat[0], toXaxis); VMOVE(&to_mat[4], toYaxis); VMOVE(&to_mat[8], toZaxis); bn_mat_inv(toinv_mat, to_mat); MAT_DELTAS_VEC(toinv_mat, translate_to); bn_mat_mul(mat, toinv_mat, from_mat); } dotg->AddMember(comb,member,mat); } Factory::DeleteObjects(); } } } if (!dotg->WriteCombs()) { std::cerr << "Error writing BRL-CAD hierarchy." << std::endl; } return true; }
static ON_Brep* MakeTrimmedPlane( ON_TextLog& error_log ) { // This example demonstrates how to construct a ON_Brep // with the topology shown below. // // // E-------C--------D // | /\ | // | / \ | // | / \ | // | e2 e1 | // | / \ | // | / \ | // | / \ | // A-----e0-------->B // // // Things need to be defined in a valid brep: // 1- Vertices // 2- 3D Curves (geometry) // 3- Edges (topology - reference curve geometry) // 4- Surface (geometry) // 5- Faces (topology - reference surface geometry) // 6- Loops (2D parameter space of faces) // 4- Trims and 2D curves (2D parameter space of edges) // ON_3dPoint point[5] = { ON_3dPoint( 0.0, 0.0, 0.0 ), // point A = geometry for vertex 0 (and surface SW corner) ON_3dPoint( 10.0, 0.0, 0.0 ), // point B = geometry for vertex 1 (and surface SE corner) ON_3dPoint( 5.0, 10.0, 0.0 ), // point C = geometry for vertex 2 ON_3dPoint( 10.0, 10.0, 0.0 ), // point D (surface NE corner) ON_3dPoint( 0.0, 10.0, 0.0 ), // point E (surface NW corner) }; ON_Brep* brep = new ON_Brep(); // create three vertices located at the three points int vi; for ( vi = 0; vi < 3; vi++ ) { ON_BrepVertex& v = brep->NewVertex(point[vi]); v.m_tolerance = 0.0; // this simple example is exact - for models with // non-exact data, set tolerance as explained in // definition of ON_BrepVertex. } // Create 3d curve geometry - the orientations are arbitrarily chosen // so that the end vertices are in alphabetical order. brep->m_C3.Append( CreateLinearCurve( point[A], point[B] ) ); // line AB brep->m_C3.Append( CreateLinearCurve( point[B], point[C] ) ); // line BC brep->m_C3.Append( CreateLinearCurve( point[A], point[C] ) ); // line CD // Create edge topology for each curve in the brep. CreateEdges( *brep ); // Create 3d surface geometry - the orientations are arbitrarily chosen so // that some normals point into the cube and others point out of the cube. brep->m_S.Append( CreatePlanarSurface( point[A], point[B], point[D], point[E] ) ); // ABDE // Create face topology and 2d parameter space loops and trims. CreateFaces( *brep ); //Make sure b-rep is valid if ( !brep->IsValid() ) { error_log.Print("Trimmed b-rep face is not valid.\n"); delete brep; brep = NULL; } return brep; }
int main(int argc, char *argv[]) { struct rt_wdb *wdbp = NULL; const char *name = "brep"; ON_Brep *brep = NULL; int ret; if ( BU_STR_EQUAL(argv[1],"-h") || BU_STR_EQUAL(argv[1],"-?")) { printusage(); return 0; } if (argc >= 1) { printusage(); fprintf(stderr," Program continues running (will create file breplicator.g):\n"); } bu_log("Breplicating...please wait...\n"); ON_3dPoint points[8] = { /* left */ ON_3dPoint(0.0, 0.0, 0.0), // 0 ON_3dPoint(1.0, 0.0, 0.0), // 1 ON_3dPoint(1.0, 0.0, 2.5), // 2 ON_3dPoint(0.0, 0.0, 2.5), // 3 /* right */ ON_3dPoint(0.0, 1.0, 0.0), // 4 ON_3dPoint(1.0, 1.0, 0.0), // 5 ON_3dPoint(1.0, 1.0, 2.5), // 6 ON_3dPoint(0.0, 1.0, 2.5), // 7 }; brep = generate_brep(8, points); if (!brep) bu_exit(1, "ERROR: We don't have a BREP\n"); ON_TextLog log(stdout); brep->Dump(log); if (!brep->IsValid(&log)) { delete brep; bu_exit(1, "ERROR: We don't have a valid BREP\n"); } brep->Dump(log); wdbp = wdb_fopen("breplicator.g"); if (!wdbp) { delete brep; bu_exit(2, "ERROR: Unable to open breplicator.g\n"); } mk_id(wdbp, "Breplicator test geometry"); bu_log("Creating the BREP as BRL-CAD geometry\n"); ret = mk_brep(wdbp, name, brep); if (ret) { delete brep; wdb_close(wdbp); bu_exit(3, "ERROR: Unable to export %s\n", name); } bu_log("Done.\n"); delete brep; wdb_close(wdbp); return 0; }
ON_Brep* MakeTwistedCube(ON_TextLog& error_log) { ON_3dPoint point[8] = { ON_3dPoint( 0.0, 0.0, 11.0), // Point A ON_3dPoint(10.0, 0.0, 12.0), // Point B ON_3dPoint(10.0, 8.0, 13.0), // Point C ON_3dPoint( 0.0, 6.0, 12.0), // Point D ON_3dPoint( 1.0, 2.0, 0.0), // Point E ON_3dPoint(10.0, 0.0, 0.0), // Point F ON_3dPoint(10.0, 7.0, -1.0), // Point G ON_3dPoint( 0.0, 6.0, 0.0), // Point H }; ON_Brep* brep = new ON_Brep(); // create eight vertices located at the eight points for (int i = 0; i < 8; i++) { ON_BrepVertex& v = brep->NewVertex(point[i]); v.m_tolerance = 0.0; // this example uses exact tolerance... reference // ON_BrepVertex for definition of non-exact data } // create 3d curve geometry - the orientations are arbitrarily // chosen so that the end vertices are in alphabetical order brep->m_C3.Append(TwistedCubeEdgeCurve(point[A], point[B])); // AB brep->m_C3.Append(TwistedCubeEdgeCurve(point[B], point[C])); // BC brep->m_C3.Append(TwistedCubeEdgeCurve(point[C], point[D])); // CD brep->m_C3.Append(TwistedCubeEdgeCurve(point[A], point[D])); // AD brep->m_C3.Append(TwistedCubeEdgeCurve(point[E], point[F])); // EF brep->m_C3.Append(TwistedCubeEdgeCurve(point[F], point[G])); // FG brep->m_C3.Append(TwistedCubeEdgeCurve(point[G], point[H])); // GH brep->m_C3.Append(TwistedCubeEdgeCurve(point[E], point[H])); // EH brep->m_C3.Append(TwistedCubeEdgeCurve(point[A], point[E])); // AE brep->m_C3.Append(TwistedCubeEdgeCurve(point[B], point[F])); // BF brep->m_C3.Append(TwistedCubeEdgeCurve(point[C], point[G])); // CG brep->m_C3.Append(TwistedCubeEdgeCurve(point[D], point[H])); // DH // create the 12 edges the connect the corners MakeTwistedCubeEdges( *brep ); // create the 3d surface geometry. the orientations are arbitrary so // some normals point into the cube and other point out... not sure why brep->m_S.Append(TwistedCubeSideSurface(point[A], point[B], point[C], point[D])); brep->m_S.Append(TwistedCubeSideSurface(point[B], point[F], point[G], point[C])); brep->m_S.Append(TwistedCubeSideSurface(point[F], point[E], point[H], point[G])); brep->m_S.Append(TwistedCubeSideSurface(point[E], point[A], point[D], point[H])); brep->m_S.Append(TwistedCubeSideSurface(point[E], point[F], point[B], point[A])); brep->m_S.Append(TwistedCubeSideSurface(point[D], point[C], point[G], point[H])); // create the faces MakeTwistedCubeFaces(*brep); if (!brep->IsValid()) { error_log.Print("Twisted cube b-rep is not valid!\n"); delete brep; brep = NULL; } return brep; }
static ON_Brep* MakeTwistedCube( ON_TextLog& error_log ) { // This example demonstrates how to construct a ON_Brep // with the topology shown below. // // // H-------e6-------G // / /| // / | / | // / e7 / e5 // / | / | // / e10 | // / | / | // e11 E- - e4- -/- - - F // / / / // / / / / // D---------e2-----C e9 // | / | / // | e8 | / // e3 / e1 / // | | / // | / | / // | |/ // A-------e0-------B // // ON_3dPoint point[8] = { ON_3dPoint( 0.0, 0.0, 0.0 ), // point A = geometry for vertex 0 ON_3dPoint( 10.0, 0.0, 0.0 ), // point B = geometry for vertex 1 ON_3dPoint( 10.0, 8.0, -1.0 ), // point C = geometry for vertex 2 ON_3dPoint( 0.0, 6.0, 0.0 ), // point D = geometry for vertex 3 ON_3dPoint( 1.0, 2.0, 11.0 ), // point E = geometry for vertex 4 ON_3dPoint( 10.0, 0.0, 12.0 ), // point F = geometry for vertex 5 ON_3dPoint( 10.0, 7.0, 13.0 ), // point G = geometry for vertex 6 ON_3dPoint( 0.0, 6.0, 12.0 ) // point H = geometry for vertex 7 }; ON_Brep* brep = new ON_Brep(); // create eight vertices located at the eight points int vi; for ( vi = 0; vi < 8; vi++ ) { ON_BrepVertex& v = brep->NewVertex(point[vi]); v.m_tolerance = 0.0; // this simple example is exact - for models with // non-exact data, set tolerance as explained in // definition of ON_BrepVertex. } // Create 3d curve geometry - the orientations are arbitrarily chosen // so that the end vertices are in alphabetical order. brep->m_C3.Append( TwistedCubeEdgeCurve( point[A], point[B] ) ); // line AB brep->m_C3.Append( TwistedCubeEdgeCurve( point[B], point[C] ) ); // line BC brep->m_C3.Append( TwistedCubeEdgeCurve( point[C], point[D] ) ); // line CD brep->m_C3.Append( TwistedCubeEdgeCurve( point[A], point[D] ) ); // line AD brep->m_C3.Append( TwistedCubeEdgeCurve( point[E], point[F] ) ); // line EF brep->m_C3.Append( TwistedCubeEdgeCurve( point[F], point[G] ) ); // line FG brep->m_C3.Append( TwistedCubeEdgeCurve( point[G], point[H] ) ); // line GH brep->m_C3.Append( TwistedCubeEdgeCurve( point[E], point[H] ) ); // line EH brep->m_C3.Append( TwistedCubeEdgeCurve( point[A], point[E] ) ); // line AE brep->m_C3.Append( TwistedCubeEdgeCurve( point[B], point[F] ) ); // line BF brep->m_C3.Append( TwistedCubeEdgeCurve( point[C], point[G] ) ); // line CG brep->m_C3.Append( TwistedCubeEdgeCurve( point[D], point[H] ) ); // line DH // Create the 12 edges that connect the corners of the cube. MakeTwistedCubeEdges( *brep ); // Create 3d surface geometry - the orientations are arbitrarily chosen so // that some normals point into the cube and others point out of the cube. brep->m_S.Append( TwistedCubeSideSurface( point[A], point[B], point[C], point[D] ) ); // ABCD brep->m_S.Append( TwistedCubeSideSurface( point[B], point[C], point[G], point[F] ) ); // BCGF brep->m_S.Append( TwistedCubeSideSurface( point[C], point[D], point[H], point[G] ) ); // CDHG brep->m_S.Append( TwistedCubeSideSurface( point[A], point[D], point[H], point[E] ) ); // ADHE brep->m_S.Append( TwistedCubeSideSurface( point[A], point[B], point[F], point[E] ) ); // ABFE brep->m_S.Append( TwistedCubeSideSurface( point[E], point[F], point[G], point[H] ) ); // EFGH // Create the CRhinoBrepFaces MakeTwistedCubeFaces( *brep ); if ( !brep->IsValid() ) { error_log.Print("Twisted cube b-rep is not valid.\n"); delete brep; brep = NULL; } //ON_BOOL32 bIsManifold; //ON_BOOL32 bHasBoundary; //ON_BOOL32 b = brep->IsManifold( &bIsManifold,&bHasBoundary ); return brep; }