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; }
CRhinoCommand::result CCommandTestHistoryExample::RunCommand( const CRhinoCommandContext& context ) { CRhinoCommand::result rc = CRhinoCommand::failure; CRhinoGetObject go; go.SetCommandPrompt(L"Pick two curves"); go.SetGeometryFilter(CRhinoGetObject::curve_object); go.GetObjects(2,2); if( go.Result()== CRhinoGet::object && go.ObjectCount()==2) { CRhinoObjRef CObj0 = go.Object(0); CRhinoObjRef CObj1 = go.Object(1); const ON_Curve* c0 = CObj0.Curve(); const ON_Curve* c1 = CObj1.Curve(); if( c0 && c1) { ON_Surface* pSrf = MakeBilinearSurface( *c0, *c1); ON_Brep brep; if(pSrf && brep.Create(pSrf)) { CRhinoHistory history(*this); WriteHistory(history, CObj0, CObj1); context.m_doc.AddBrepObject(brep,NULL,&history); rc = CRhinoCommand::success; } } } return rc; }
ON_Brep* ON_Surface::BrepForm( ON_Brep* brep ) const { ON_Brep* pBrep = NULL; if ( brep ) brep->Destroy(); // 26 August 2008 Dale Lear - fixed bug // When this function was called on an ON_SurfaceProxy //ON_Surface* pSurface = Duplicate(); ON_Surface* pSurface = DuplicateSurface(); if ( pSurface ) { if ( brep ) pBrep = brep; else pBrep = new ON_Brep(); if ( !pBrep->Create(pSurface) ) { if ( pSurface ) { delete pSurface; pSurface = NULL; } if ( !brep ) delete pBrep; pBrep = NULL; } } return pBrep; }
vtkActor* gfxRhino3D::createActor(const ON_Object *object, double red, double green, double blue){ ON_Brep *brep; ON_SimpleArray<const ON_Mesh*> cmsh; int i, j, k, l, npts; double x1,x2,x3,x4, y1,y2,y3,y4, z1,z2,z3,z4; // Add Meshes to list parentObject->points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> list = vtkSmartPointer<vtkCellArray>::New(); brep=0; brep = (ON_Brep*)ON_Brep::Cast(object); if (brep){ brep->GetMesh(ON::render_mesh, cmsh); if (cmsh.Count()>0){ for (l=0;l<cmsh.Count();l++){ npts=parentObject->points->GetNumberOfPoints(); for (j=0;j<cmsh[l]->m_V.Count();j++) parentObject->points->InsertNextPoint(cmsh[l]->m_V[j].x, cmsh[l]->m_V[j].y, cmsh[l]->m_V[j].z); for (j=0;j<cmsh[l]->m_F.Count();j++){ if (cmsh[l]->m_F[j].IsTriangle()){ vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New(); for (k=0;k<3;k++) triangle->GetPointIds()->SetId(k,cmsh[l]->m_F[j].vi[k]+npts); list->InsertNextCell(triangle); }else{ vtkSmartPointer<vtkQuad> quad = vtkSmartPointer<vtkQuad>::New(); for (k=0;k<4;k++) quad->GetPointIds()->SetId(k,cmsh[l]->m_F[j].vi[k]+npts); list->InsertNextCell(quad); } } } } } //Create a polydata object and add data vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New(); polydata->SetPoints(parentObject->points); polydata->SetPolys(list); //Create Mapper vtkPolyDataMapper *mapper = vtkPolyDataMapper::New(); mapper->SetInput(polydata); mapper->SetScalarRange(0.,1.); //Create Actor vtkActor *tmpActor = vtkActor::New(); tmpActor->SetMapper(mapper); tmpActor->GetProperty()->SetInterpolationToGouraud(); // void SetInterpolationToFlat() // void SetInterpolationToGouraud() // void SetInterpolationToPhong() tmpActor->GetProperty()->SetColor(red, green, blue); return tmpActor; }
static bool ON_BrepExtrudeHelper_MakeCap( ON_Brep& brep, int bottom_loop_index, const ON_3dVector path_vector, const int* side_face_index ) { bool bCap = true; // make cap if ( !ON_BrepExtrudeHelper_CheckLoop( brep, bottom_loop_index ) ) return false; brep.m_F.Reserve(brep.m_F.Count() + 1); brep.m_L.Reserve(brep.m_L.Count() + 1); const ON_BrepLoop& bottom_loop = brep.m_L[bottom_loop_index]; const ON_BrepFace& bottom_face = brep.m_F[bottom_loop.m_fi]; const ON_Surface* bottom_surface = bottom_face.SurfaceOf(); ON_Surface* top_surface = bottom_surface->Duplicate(); top_surface->Translate( path_vector ); int top_surface_index = brep.AddSurface( top_surface ); ON_BrepFace& top_face = brep.NewFace( top_surface_index ); bCap = ON_BrepExtrudeHelper_MakeTopLoop( brep, top_face, bottom_loop_index, path_vector, side_face_index ); if ( bCap ) { ON_BrepLoop& top_loop = brep.m_L[brep.m_L.Count()-1]; if ( bottom_loop.m_type == ON_BrepLoop::inner ) { // we capped an inner boundary // top_loop.m_type = ON_BrepLoop::outer; // done in ON_BrepExtrudeHelper_MakeTopLoop brep.FlipLoop(top_loop); } else if ( bottom_loop.m_type == ON_BrepLoop::outer ) { // we capped an outer boundary // top_loop.m_type = ON_BrepLoop::outer; // done in ON_BrepExtrudeHelper_MakeTopLoop brep.FlipFace(top_face); } } else { // delete partially made cap face brep.DeleteFace( top_face, false ); delete brep.m_S[top_surface_index]; brep.m_S[top_surface_index] = 0; } return bCap; }
static void MakeTrimmedFace( ON_Brep& brep, int si, // index of 3d surface int s_dir, // orientation of surface with respect to surfce int v0, int v1, int v2, // Indices of corner vertices int e0, // index of first edge int e0_dir, // orientation of edge int e1, // index of second edge int e1_dir, // orientation of edge int e2, // index of third edge int e2_dir // orientation of edge ) { //Add new face to brep ON_BrepFace& face = brep.NewFace(si); //Create loop and trims for the face MakeTrimmingLoop( brep, face, v0, v1, v2, e0, e0_dir, e1, e1_dir, e2, e2_dir ); //Set face direction relative to surface direction face.m_bRev = (s_dir == -1); }
static void MakeTwistedCubeFace( ON_Brep& brep, int si, // index of 3d surface int s_dir, // orientation of surface with respect to brep //int vSWi, int vSEi, int vNEi, int vNWi, // Indices of corner vertices listed in SW,SE,NW,NE order int eSi, // index of edge on south side of surface int eS_dir, // orientation of edge with respect to surface trim int eEi, // index of edge on south side of surface int eE_dir, // orientation of edge with respect to surface trim int eNi, // index of edge on south side of surface int eN_dir, // orientation of edge with respect to surface trim int eWi, // index of edge on south side of surface int eW_dir // orientation of edge with respect to surface trim ) { ON_BrepFace& face = brep.NewFace(si); MakeTwistedCubeTrimmingLoop( brep, face, //vSWi, vSEi, vNEi, vNWi, eSi, eS_dir, eEi, eE_dir, eNi, eN_dir, eWi, eW_dir ); face.m_bRev = (s_dir == -1); }
void MakeTwistedCubeEdge(ON_Brep& brep, int from, int to, int curve) { ON_BrepVertex& v0 = brep.m_V[from]; ON_BrepVertex& v1 = brep.m_V[to]; ON_BrepEdge& edge = brep.NewEdge(v0,v1,curve); edge.m_tolerance = 0.0; // exact! }
// ANSWER: // An ON_BrepEdge is connector for joining ON_BrepTrim objects and representing // a 3-D location of the seam they form. An Edge can connect 1 or more trims. // In the case of a simple "joined edge" there will be 2 trims, one from each // adjacent face. In a closed face, like a cylinder, the trims will be different // on each side of the face, and they will both be in the same loop and belong to // the same face. static const ON_BrepFace* GetOtherFace(const ON_BrepTrim* trim) { ON_BrepFace* face = 0; if (0 == trim) return 0; ON_Brep* brep = trim->Brep(); if (0 == brep) return 0; const ON_BrepEdge* edge = trim->Edge(); if (0 == edge) return 0; // Trim count on a proper joined edge should be 2. const int trim_count = edge->TrimCount(); if (trim_count < 2) return 0; // Not joined if (trim_count > 2) return 0; // Joined to more than one other surface (non-manifold) for (int i = 0; i < trim_count; i++) { // Look for a trim that's not the same as the input one // edge->m_ti is an array of indexes of the trims connected to an edge const ON_BrepTrim* other_trim = brep->Trim(edge->m_ti[i]); if (0 != other_trim && trim != other_trim) { // There is another trim on the edge, and its not the same as the input one. // So get the face it belonge to. face = other_trim->Face(); // You can also get the loop on the other side of the edge //const ON_BrepLoop* other_loop = other_trim->Loop(); // Or the surface geometry of the face //const ON_Surface* srf = face->SurfaceOf(); break; } } return face; }
/* TODO - Need to find a more compact, efficient way to * do this - shouldn't need 24 3d curves... */ ON_Brep * Cobb_Sphere(double UNUSED(radius), ON_3dPoint *UNUSED(origin)) { ON_Brep *b = ON_Brep::New(); // Patch 1 of 6 ON_BezierSurface *b1 = ON_CobbSphereFace(0, 0); ON_NurbsSurface *p1_nurb = ON_NurbsSurface::New(); b1->GetNurbForm(*p1_nurb); b->NewFace(*p1_nurb); // Patch 2 of 6 ON_BezierSurface *b2 = ON_CobbSphereFace(90, 0); ON_NurbsSurface *p2_nurb = ON_NurbsSurface::New(); b2->GetNurbForm(*p2_nurb); b->NewFace(*p2_nurb); // Patch 3 of 6 ON_BezierSurface *b3 = ON_CobbSphereFace(180, 0); ON_NurbsSurface *p3_nurb = ON_NurbsSurface::New(); b3->GetNurbForm(*p3_nurb); b->NewFace(*p3_nurb); // Patch 4 of 6 ON_BezierSurface *b4 = ON_CobbSphereFace(270, 0); ON_NurbsSurface *p4_nurb = ON_NurbsSurface::New(); b4->GetNurbForm(*p4_nurb); b->NewFace(*p4_nurb); // Patch 5 of 6 ON_BezierSurface *b5 = ON_CobbSphereFace(90, 90); ON_NurbsSurface *p5_nurb = ON_NurbsSurface::New(); b5->GetNurbForm(*p5_nurb); b->NewFace(*p5_nurb); // Patch 6 of 6 ON_BezierSurface *b6 = ON_CobbSphereFace(90, 270); ON_NurbsSurface *p6_nurb = ON_NurbsSurface::New(); b6->GetNurbForm(*p6_nurb); b->NewFace(*p6_nurb); b->Standardize(); b->Compact(); return b; }
int ON_BrepExtrudeVertex( ON_Brep& brep, int vertex_index, const ON_Curve& path_curve ) { ON_3dVector path_vector; if ( vertex_index < 0 && vertex_index >= brep.m_V.Count() ) return false; if ( !ON_BrepExtrudeHelper_CheckPathCurve(path_curve,path_vector) ) return false; ON_Curve* c3 = path_curve.Duplicate(); brep.m_V.Reserve( brep.m_V.Count() + 1 ); ON_BrepVertex& v0 = brep.m_V[vertex_index]; ON_BrepVertex& v1 = brep.NewVertex( v0.point + path_vector, 0.0 ); c3->Translate( v0.point - c3->PointAtStart() ); int c3i = brep.AddEdgeCurve( c3 ); ON_BrepEdge& edge = brep.NewEdge( v0, v1, c3i ); edge.m_tolerance = 0.0; return true; }
RH_C_FUNCTION ON_Brep* ON_Brep_CopyTrims( const ON_BrepFace* pConstBrepFace, const ON_Surface* pConstSurface, double tolerance) { ON_Brep* rc = NULL; if( pConstBrepFace && pConstSurface ) { ON_Brep* brep = pConstBrepFace->Brep(); int fi = pConstBrepFace->m_face_index; ON_Brep* brp = brep->DuplicateFace(fi, FALSE); ON_Surface* srf = pConstSurface->DuplicateSurface(); int si = brp->AddSurface(srf); brp->m_F[0].ChangeSurface(si); if (brp->RebuildEdges(brp->m_F[0], tolerance, TRUE, TRUE)) { brp->Compact(); } else { delete brp; } rc = brp; } return rc; }
static bool ChangeTrimVertex( ON_Brep& brep, ON_BrepTrim& trim, int trim_end, int old_vi, int new_vi, bool bUpdateEdge, bool bUpdateMates ) { // used by ON_Brep::ReplaceSurface() to change trim ends if ( trim_end != 0 && trim_end != 1 ) return false; if ( trim.m_vi[trim_end] != old_vi ) return false; if ( old_vi == new_vi ) return true; trim.m_vi[trim_end] = new_vi; ON_BrepVertex* v = brep.Vertex(old_vi); if ( v ) v->m_tolerance = ON_UNSET_VALUE; v = brep.Vertex(new_vi); if ( v ) v->m_tolerance = ON_UNSET_VALUE; bool rc = true; if ( bUpdateEdge ) { ON_BrepEdge* edge = brep.Edge(trim.m_ei); if ( 0 == edge ) return true; int edge_end = trim.m_bRev3d ? 1-trim_end : trim_end; rc = ChangeEdgeVertex( brep, *edge, edge_end, old_vi, new_vi, bUpdateMates ); } return true; }
RH_C_FUNCTION ON_Brep* ON_BrepFace_BrepExtrudeFace(const ON_Brep* pConstBrep, int face_index, const ON_Curve* pConstCurve, bool bCap) { ON_Brep* rc = NULL; if( pConstBrep && pConstCurve ) { if( face_index >= 0 && face_index < pConstBrep->m_F.Count() ) { ON_Brep* pNewBrep = ON_Brep::New( *pConstBrep ); if( pNewBrep ) { pNewBrep->DestroyMesh( ON::any_mesh ); int result = ON_BrepExtrudeFace( *pNewBrep, face_index, *pConstCurve, bCap ); // 0 == failure, 1 or 2 == success if( 0 == result ) delete pNewBrep; else rc = pNewBrep; } } } return rc; }
static void CreateOneEdge( ON_Brep& brep, int vi0, // index of start vertex int vi1, // index of end vertex int c3i // index of 3d curve ) { ON_BrepVertex& v0 = brep.m_V[vi0]; ON_BrepVertex& v1 = brep.m_V[vi1]; ON_BrepEdge& edge = brep.NewEdge(v0,v1,c3i); edge.m_tolerance = 0.0; // this simple example is exact - for models with // non-exact data, set tolerance as explained in // definition of ON_BrepEdge. }
static bool RebuildVertexToTrimEnd(ON_BrepTrim& T, int end) { ON_Brep* pB = T.Brep(); if (!pB) return false; int vid = T.m_vi[end]; if (vid < 0) return false; ON_BrepVertex& V = pB->m_V[vid]; ON_3dPoint P; if (end){ if (!pB->GetTrim3dEnd(T.m_trim_index, P)) return false; } else { if (!pB->GetTrim3dStart(T.m_trim_index, P)) return false; } V.SetPoint(P); return true; }
RH_C_FUNCTION ON_Brep* ON_Brep_FromSurface( const ON_Surface* pConstSurface ) { ON_Brep* rc = NULL; if( pConstSurface ) { ON_Brep* pNewBrep = ON_Brep::New(); if( pNewBrep ) { ON_Surface* pNewSurface = pConstSurface->DuplicateSurface(); if( pNewSurface ) { if( pNewBrep->Create(pNewSurface) ) rc = pNewBrep; if( NULL==rc ) delete pNewSurface; } if( NULL==rc ) delete pNewBrep; } } return rc; }
int ON_BrepExtrudeEdge( ON_Brep& brep, int edge_index, const ON_Curve& path_curve ) { ON_3dVector path_vector; if ( edge_index < 0 && edge_index >= brep.m_E.Count() ) return false; if ( !ON_BrepExtrudeHelper_CheckPathCurve(path_curve,path_vector) ) return false; // make sides bool bRev = false; ON_SumSurface* sum_srf = ON_BrepExtrudeHelper_MakeSumSrf( path_curve, brep.m_E[edge_index], bRev ); if ( !sum_srf ) return false; int vid[4], eid[4], bRev3d[4]; vid[0] = brep.m_E[edge_index].m_vi[bRev?0:1]; vid[1] = brep.m_E[edge_index].m_vi[bRev?1:0]; vid[2] = -1; vid[3] = -1; eid[0] = edge_index; // "south side edge" eid[1] = -1; eid[2] = -1; eid[3] = -1; bRev3d[0] = bRev?0:1; bRev3d[1] = 0; bRev3d[2] = 0; bRev3d[3] = 0; return brep.NewFace( sum_srf, vid, eid, bRev3d ) ? true : false; }
int ON_BrepExtrudeLoop( ON_Brep& brep, int loop_index, const ON_Curve& path_curve, bool bCap ) { ON_SimpleArray<int> side_face_index; // index of new face above brep.m_L[loop_index].m_ti[lti] ON_3dVector path_vector; const int face_count0 = brep.m_F.Count(); if ( loop_index < 0 || loop_index >= brep.m_L.Count() ) return false; if ( !ON_BrepExtrudeHelper_CheckPathCurve(path_curve,path_vector) ) return false; // can only cap closed loops ( for now, just test for inner and outer loops). if ( brep.m_L[loop_index].m_type != ON_BrepLoop::outer && brep.m_L[loop_index].m_type != ON_BrepLoop::inner ) bCap = false; // make sides if ( !ON_BrepExtrudeHelper_MakeSides( brep, loop_index, path_curve, bCap, side_face_index ) ) return false; // make cap if ( bCap ) bCap = ON_BrepExtrudeHelper_MakeCap( brep, loop_index, path_vector, side_face_index.Array() ); const ON_BrepLoop& loop = brep.m_L[loop_index]; if ( loop.m_fi >= 0 && loop.m_fi < brep.m_F.Count() && brep.m_F[loop.m_fi].m_bRev ) { for ( int fi = face_count0; fi < brep.m_F.Count(); fi++ ) { brep.FlipFace( brep.m_F[fi] ); } } return (bCap?2:1); }
void MakeTwistedCubeFace(ON_Brep& brep, int surf, int orientation, int v0, int v1, int v2, int v3, // the indices of corner vertices int e0, int eo0, // edge index + orientation int e1, int eo1, int e2, int eo2, int e3, int eo3) { ON_BrepFace& face = brep.NewFace(surf); MakeTwistedCubeTrimmingLoop(brep, face, v0, v1, v2, v3, e0, eo0, e1, eo1, e2, eo2, e3, eo3); // should the normal be reversed? face.m_bRev = (orientation == -1); }
int ON_BrepConeEdge( ON_Brep& brep, int edge_index, ON_3dPoint apex_point ) { //ON_3dVector path_vector; if ( edge_index < 0 && edge_index >= brep.m_E.Count() ) return false; // make sides ON_NurbsSurface* cone_srf = ON_BrepExtrudeHelper_MakeConeSrf( apex_point, brep.m_E[edge_index], false ); if ( !cone_srf ) return false; int vid[4], eid[4], bRev3d[4]; vid[0] = brep.m_E[edge_index].m_vi[0]; vid[1] = brep.m_E[edge_index].m_vi[1]; vid[2] = -1; vid[3] = -1; eid[0] = edge_index; eid[1] = -1; eid[2] = -1; eid[3] = -1; bRev3d[0] = 0; bRev3d[1] = 0; bRev3d[2] = 0; bRev3d[3] = 0; return brep.NewFace( cone_srf, vid, eid, bRev3d ) ? true : false; }
static bool SealSeam(int closed_dir, ON_BrepFace& F) { if (closed_dir) closed_dir = 1; int seam_dir = 1-closed_dir; ON_Brep* pBrep = F.Brep(); if (!pBrep) return false; const ON_Surface* pSrf = F.SurfaceOf(); if (!pSrf || !pSrf->IsClosed(closed_dir)) return false; ON_Surface::ISO isoA = ON_Surface::not_iso;//same dir as isocurve ON_Surface::ISO isoB = ON_Surface::not_iso;//opposite dir as isocurve if (closed_dir){ isoA = ON_Surface::S_iso; isoB = ON_Surface::N_iso; } else { isoA = ON_Surface::E_iso; isoB = ON_Surface::W_iso; } /* TODO: Handle cases where there is more than one trim on a seam side or seam edges do not fully overlap. */ //Look for a single pair of trims that match across parameter space. int A_id = -1; int B_id = -1; int li; for (li=0; li<F.m_li.Count(); li++){ const ON_BrepLoop* L = F.Loop(li); if (!L || L->m_type != ON_BrepLoop::outer) continue; int lti; for (lti = 0; lti<L->m_ti.Count(); lti++ ){ ON_BrepTrim* T = L->Trim(lti); if (!T) continue; if (T->m_iso == isoA) { if (A_id >= 0) return false; A_id = T->m_trim_index; } else if (T->m_iso == isoB) { if (B_id >= 0) return false; B_id = T->m_trim_index; } } } if (A_id < 0 || B_id < 0) return true;//no seam to join ON_BrepTrim& TA = pBrep->m_T[A_id]; ON_BrepTrim& TB = pBrep->m_T[B_id]; ON_BrepEdge* pEA = TA.Edge(); ON_BrepEdge* pEB = TB.Edge(); if (!pEA || !pEB) return false; ON_Interval a,b; int i; for (i=0; i<2; i++){ a[i] = TA.PointAt(TA.Domain()[i])[seam_dir]; b[i] = TB.PointAt(TB.Domain()[i])[seam_dir]; } a.MakeIncreasing(); b.MakeIncreasing(); if (a[0] >= b[1] || b[0] >= a[1]) return true; //nothing to be joined; double pspace_tol = 1.0e-8; if (a.Length() < 10.0*pspace_tol) return false; if (fabs(a[0] - b[0]) > pspace_tol || fabs(a[1] - b[1]) > pspace_tol) return false; //fix vertices so join will work. RebuildVertexToTrimEnd(TA, 0); RebuildVertexToTrimEnd(TA, 1); RebuildVertexToTrimEnd(TB, 0); RebuildVertexToTrimEnd(TB, 1); double join_tol = 1.0e-6; if (!pBrep->JoinEdges(*pEA, *pEB, join_tol)) return false; TA.m_type = ON_BrepTrim::seam; TB.m_type = ON_BrepTrim::seam; 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; }
static ON_Brep * generate_brep(int count, ON_3dPoint *points) { ON_Brep *brep = new ON_Brep(); /* make an arb8 */ // VERTICES for (int i=0; i<count; i++) { brep->NewVertex(points[i], SMALL_FASTF); } ON_3dPoint p8 = ON_3dPoint(-1.0, 0.0, -1.0); ON_3dPoint p9 = ON_3dPoint(2.0, 0.0, -1.0); ON_3dPoint p10 = ON_3dPoint(2.0, 0.0, 3.5); ON_3dPoint p11 = ON_3dPoint(-1.0, 0.0, 3.5); brep->NewVertex(p8, SMALL_FASTF); // 8 brep->NewVertex(p9, SMALL_FASTF); // 9 brep->NewVertex(p10, SMALL_FASTF); // 10 brep->NewVertex(p11, SMALL_FASTF); // 11 // LEFT SEGMENTS // 0 ON_Curve* segment01 = new ON_LineCurve(points[0], points[1]); segment01->SetDomain(0.0, 1.0); brep->m_C3.Append(segment01); // 1 ON_Curve* segment12 = new ON_LineCurve(points[1], points[2]); segment12->SetDomain(0.0, 1.0); brep->m_C3.Append(segment12); // 2 ON_Curve* segment23 = new ON_LineCurve(points[2], points[3]); segment23->SetDomain(0.0, 1.0); brep->m_C3.Append(segment23); // 3 ON_Curve* segment30 = new ON_LineCurve(points[3], points[0]); segment30->SetDomain(0.0, 1.0); brep->m_C3.Append(segment30); // RIGHT SEGMENTS // 4 ON_Curve* segment45 = new ON_LineCurve(points[5], points[4]); segment45->SetDomain(0.0, 1.0); brep->m_C3.Append(segment45); // 5 ON_Curve* segment56 = new ON_LineCurve(points[6], points[5]); segment56->SetDomain(0.0, 1.0); brep->m_C3.Append(segment56); // 6 ON_Curve* segment67 = new ON_LineCurve(points[7], points[6]); segment67->SetDomain(0.0, 1.0); brep->m_C3.Append(segment67); // 7 ON_Curve* segment74 = new ON_LineCurve(points[4], points[7]); segment74->SetDomain(0.0, 1.0); brep->m_C3.Append(segment74); // HORIZONTAL SEGMENTS // 8 ON_Curve* segment04 = new ON_LineCurve(points[0], points[4]); segment04->SetDomain(0.0, 1.0); brep->m_C3.Append(segment04); // 9 ON_Curve* segment51 = new ON_LineCurve(points[5], points[1]); segment51->SetDomain(0.0, 1.0); brep->m_C3.Append(segment51); // 10 ON_Curve* segment26 = new ON_LineCurve(points[2], points[6]); segment26->SetDomain(0.0, 1.0); brep->m_C3.Append(segment26); // 11 ON_Curve* segment73 = new ON_LineCurve(points[7], points[3]); segment73->SetDomain(0.0, 1.0); brep->m_C3.Append(segment73); /* XXX */ // 12 ON_Curve* segment01prime = new ON_LineCurve(p8, p9); segment01prime->SetDomain(0.0, 1.0); brep->m_C3.Append(segment01prime); // 13 ON_Curve* segment12prime = new ON_LineCurve(p9, p10); segment12prime->SetDomain(0.0, 1.0); brep->m_C3.Append(segment12prime); // 14 ON_Curve* segment23prime = new ON_LineCurve(p10, p11); segment23prime->SetDomain(0.0, 1.0); brep->m_C3.Append(segment23prime); // 15 ON_Curve* segment30prime = new ON_LineCurve(p11, p8); segment30prime->SetDomain(0.0, 1.0); brep->m_C3.Append(segment30prime); // SURFACES ON_NurbsSurface* surf0123 = new ON_NurbsSurface(3 /*dimension*/, 0 /*nonrational*/, 2 /*u*/, 2 /*v*/, 2 /*#u*/, 2 /*#v*/); surf0123->SetKnot(0, 0, 0.0); surf0123->SetKnot(0, 1, 1.0); surf0123->SetKnot(1, 0, 0.0); surf0123->SetKnot(1, 1, 1.0); surf0123->SetCV(0, 0, points[0]); surf0123->SetCV(1, 0, points[1]); surf0123->SetCV(1, 1, points[2]); surf0123->SetCV(0, 1, points[3]); brep->m_S.Append(surf0123); /* 0 */ ON_NurbsSurface* surf4765 = new ON_NurbsSurface(3 /*dimension*/, 0 /*nonrational*/, 2 /*u*/, 2 /*v*/, 2 /*#u*/, 2 /*#v*/); surf4765->SetKnot(0, 0, 0.0); surf4765->SetKnot(0, 1, 1.0); surf4765->SetKnot(1, 0, 0.0); surf4765->SetKnot(1, 1, 1.0); surf4765->SetCV(0, 0, points[4]); surf4765->SetCV(1, 0, points[7]); surf4765->SetCV(1, 1, points[6]); surf4765->SetCV(0, 1, points[5]); brep->m_S.Append(surf4765); /* 1 */ ON_NurbsSurface* surf0451 = new ON_NurbsSurface(3 /*dimension*/, 0 /*nonrational*/, 2 /*u*/, 2 /*v*/, 2 /*#u*/, 2 /*#v*/); surf0451->SetKnot(0, 0, 0.0); surf0451->SetKnot(0, 1, 1.0); surf0451->SetKnot(1, 0, 0.0); surf0451->SetKnot(1, 1, 1.0); surf0451->SetCV(0, 0, points[0]); surf0451->SetCV(1, 0, points[4]); surf0451->SetCV(1, 1, points[5]); surf0451->SetCV(0, 1, points[1]); brep->m_S.Append(surf0451); /* 2 */ ON_NurbsSurface* surf2673 = new ON_NurbsSurface(3 /*dimension*/, 0 /*nonrational*/, 2 /*u*/, 2 /*v*/, 2 /*#u*/, 2 /*#v*/); surf2673->SetKnot(0, 0, 0.0); surf2673->SetKnot(0, 1, 1.0); surf2673->SetKnot(1, 0, 0.0); surf2673->SetKnot(1, 1, 1.0); surf2673->SetCV(0, 0, points[2]); surf2673->SetCV(1, 0, points[6]); surf2673->SetCV(1, 1, points[7]); surf2673->SetCV(0, 1, points[3]); brep->m_S.Append(surf2673); /* 3 */ ON_NurbsSurface* surf1562 = new ON_NurbsSurface(3 /*dimension*/, 0 /*nonrational*/, 2 /*u*/, 2 /*v*/, 2 /*#u*/, 2 /*#v*/); surf1562->SetKnot(0, 0, 0.0); surf1562->SetKnot(0, 1, 1.0); surf1562->SetKnot(1, 0, 0.0); surf1562->SetKnot(1, 1, 1.0); surf1562->SetCV(0, 0, points[1]); surf1562->SetCV(1, 0, points[5]); surf1562->SetCV(1, 1, points[6]); surf1562->SetCV(0, 1, points[2]); brep->m_S.Append(surf1562); /* 4 */ ON_NurbsSurface* surf0374 = new ON_NurbsSurface(3 /*dimension*/, 0 /*nonrational*/, 2 /*u*/, 2 /*v*/, 2 /*#u*/, 2 /*#v*/); surf0374->SetKnot(0, 0, 0.0); surf0374->SetKnot(0, 1, 1.0); surf0374->SetKnot(1, 0, 0.0); surf0374->SetKnot(1, 1, 1.0); surf0374->SetCV(0, 0, points[0]); surf0374->SetCV(1, 0, points[3]); surf0374->SetCV(1, 1, points[7]); surf0374->SetCV(0, 1, points[4]); brep->m_S.Append(surf0374); /* 5 */ // TRIM CURVES ON_Curve* trimcurve01 = new ON_LineCurve(ON_2dPoint(0, 0), ON_2dPoint(1, 0)); trimcurve01->SetDomain(0.0, 1.0); brep->m_C2.Append(trimcurve01); /* 0 */ ON_Curve* trimcurve12 = new ON_LineCurve(ON_2dPoint(1, 0), ON_2dPoint(1, 1)); trimcurve12->SetDomain(0.0, 1.0); brep->m_C2.Append(trimcurve12); /* 1 */ ON_Curve* trimcurve23 = new ON_LineCurve(ON_2dPoint(1, 1), ON_2dPoint(0, 1)); trimcurve23->SetDomain(0.0, 1.0); brep->m_C2.Append(trimcurve23); /* 2 */ ON_Curve* trimcurve30 = new ON_LineCurve(ON_2dPoint(0, 1), ON_2dPoint(0, 0)); trimcurve30->SetDomain(0.0, 1.0); brep->m_C2.Append(trimcurve30); /* 3 */ // EDGES /* C3 curve */ // left face edges brep->NewEdge(brep->m_V[0], brep->m_V[1], 0, NULL, SMALL_FASTF); /* 0 */ brep->NewEdge(brep->m_V[1], brep->m_V[2], 1, NULL, SMALL_FASTF); /* 1 */ brep->NewEdge(brep->m_V[2], brep->m_V[3], 2, NULL, SMALL_FASTF); /* 2 */ brep->NewEdge(brep->m_V[3], brep->m_V[0], 3, NULL, SMALL_FASTF); /* 3 */ // right face edges brep->NewEdge(brep->m_V[5], brep->m_V[4], 4, NULL, SMALL_FASTF); /* 4 */ brep->NewEdge(brep->m_V[6], brep->m_V[5], 5, NULL, SMALL_FASTF); /* 5 */ brep->NewEdge(brep->m_V[7], brep->m_V[6], 6, NULL, SMALL_FASTF); /* 6 */ brep->NewEdge(brep->m_V[4], brep->m_V[7], 7, NULL, SMALL_FASTF); /* 7 */ // horizontal face edges brep->NewEdge(brep->m_V[0], brep->m_V[4], 8, NULL, SMALL_FASTF); /* 8 */ brep->NewEdge(brep->m_V[5], brep->m_V[1], 9, NULL, SMALL_FASTF); /* 9 */ brep->NewEdge(brep->m_V[2], brep->m_V[6], 10, NULL, SMALL_FASTF); /* 10 */ brep->NewEdge(brep->m_V[7], brep->m_V[3], 11, NULL, SMALL_FASTF); /* 11 */ // XXX brep->NewEdge(brep->m_V[8], brep->m_V[9], 12, NULL, SMALL_FASTF); /* 12 */ brep->NewEdge(brep->m_V[9], brep->m_V[10], 13, NULL, SMALL_FASTF); /* 13 */ brep->NewEdge(brep->m_V[10], brep->m_V[11], 14, NULL, SMALL_FASTF); /* 14 */ brep->NewEdge(brep->m_V[11], brep->m_V[8], 15, NULL, SMALL_FASTF); /* 15 */ // FACES ON_BrepFace& face0123 = brep->NewFace(0); ON_BrepLoop& loop0123 = brep->NewLoop(ON_BrepLoop::outer, face0123); /* 0 */ ON_BrepTrim& trim01 = brep->NewTrim(brep->m_E[0], false, loop0123, 0 /* trim */); /* m_T[0] */ trim01.m_iso = ON_Surface::S_iso; trim01.m_type = ON_BrepTrim::mated; trim01.m_tolerance[0] = SMALL_FASTF; trim01.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim12 = brep->NewTrim(brep->m_E[1], false, loop0123, 1 /* trim */); /* 1 */ trim12.m_iso = ON_Surface::E_iso; trim12.m_type = ON_BrepTrim::mated; trim12.m_tolerance[0] = SMALL_FASTF; trim12.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim23 = brep->NewTrim(brep->m_E[2], false, loop0123, 2 /* trim */); /* 2 */ trim23.m_iso = ON_Surface::N_iso; trim23.m_type = ON_BrepTrim::mated; trim23.m_tolerance[0] = SMALL_FASTF; trim23.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim30 = brep->NewTrim(brep->m_E[3], false, loop0123, 3 /* trim */); /* 3 */ trim30.m_iso = ON_Surface::W_iso; trim30.m_type = ON_BrepTrim::mated; trim30.m_tolerance[0] = SMALL_FASTF; trim30.m_tolerance[1] = SMALL_FASTF; ON_BrepFace& face4765 = brep->NewFace(1 /* surfaceID */); ON_BrepLoop& loop4765 = brep->NewLoop(ON_BrepLoop::outer, face4765); /* 1 */ ON_BrepTrim& trim47 = brep->NewTrim(brep->m_E[7], false, loop4765, 0 /* trim */); /* 4 */ trim47.m_iso = ON_Surface::S_iso; trim47.m_type = ON_BrepTrim::mated; trim47.m_tolerance[0] = SMALL_FASTF; trim47.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim76 = brep->NewTrim(brep->m_E[6], false, loop4765, 1 /* trim */); /* 5 */ trim76.m_iso = ON_Surface::E_iso; trim76.m_type = ON_BrepTrim::mated; trim76.m_tolerance[0] = SMALL_FASTF; trim76.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim65 = brep->NewTrim(brep->m_E[5], false, loop4765, 2 /* trim */); /* 6 */ trim65.m_iso = ON_Surface::N_iso; trim65.m_type = ON_BrepTrim::mated; trim65.m_tolerance[0] = SMALL_FASTF; trim65.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim54 = brep->NewTrim(brep->m_E[4], false, loop4765, 3 /* trim */); /* 7 */ trim54.m_iso = ON_Surface::W_iso; trim54.m_type = ON_BrepTrim::mated; trim54.m_tolerance[0] = SMALL_FASTF; trim54.m_tolerance[1] = SMALL_FASTF; ON_BrepFace& face0451 = brep->NewFace(2); ON_BrepLoop& loop0451 = brep->NewLoop(ON_BrepLoop::outer, face0451); /* 2 */ ON_BrepTrim& trim04 = brep->NewTrim(brep->m_E[8], false, loop0451, 0 /* trim */); /* 8 */ trim04.m_iso = ON_Surface::S_iso; trim04.m_type = ON_BrepTrim::mated; trim04.m_tolerance[0] = SMALL_FASTF; trim04.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim45 = brep->NewTrim(brep->m_E[4], true, loop0451, 1 /* trim */); /* 9 */ trim45.m_iso = ON_Surface::E_iso; trim45.m_type = ON_BrepTrim::mated; trim45.m_tolerance[0] = SMALL_FASTF; trim45.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim51 = brep->NewTrim(brep->m_E[9], false, loop0451, 2 /* trim */); /* 10 */ trim51.m_iso = ON_Surface::N_iso; trim51.m_type = ON_BrepTrim::mated; trim51.m_tolerance[0] = SMALL_FASTF; trim51.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim10 = brep->NewTrim(brep->m_E[0], true, loop0451, 3 /* trim */); /* 11 */ trim10.m_iso = ON_Surface::W_iso; trim10.m_type = ON_BrepTrim::mated; trim10.m_tolerance[0] = SMALL_FASTF; trim10.m_tolerance[1] = SMALL_FASTF; ON_BrepFace& face2673 = brep->NewFace(3); ON_BrepLoop& loop2673 = brep->NewLoop(ON_BrepLoop::outer, face2673); /* 3 */ ON_BrepTrim& trim26 = brep->NewTrim(brep->m_E[10], false, loop2673, 0 /* trim */); /* 12 */ trim26.m_iso = ON_Surface::S_iso; trim26.m_type = ON_BrepTrim::mated; trim26.m_tolerance[0] = SMALL_FASTF; trim26.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim67 = brep->NewTrim(brep->m_E[6], true, loop2673, 1 /* trim */); /* 13 */ trim67.m_iso = ON_Surface::E_iso; trim67.m_type = ON_BrepTrim::mated; trim67.m_tolerance[0] = SMALL_FASTF; trim67.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim73 = brep->NewTrim(brep->m_E[11], false, loop2673, 2 /* trim */); /* 14 */ trim73.m_iso = ON_Surface::N_iso; trim73.m_type = ON_BrepTrim::mated; trim73.m_tolerance[0] = SMALL_FASTF; trim73.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim32 = brep->NewTrim(brep->m_E[2], true, loop2673, 3 /* trim */); /* 15 */ trim32.m_iso = ON_Surface::W_iso; trim32.m_type = ON_BrepTrim::mated; trim32.m_tolerance[0] = SMALL_FASTF; trim32.m_tolerance[1] = SMALL_FASTF; ON_BrepFace& face1562 = brep->NewFace(4); ON_BrepLoop& loop1562 = brep->NewLoop(ON_BrepLoop::outer, face1562); /* 4 */ ON_BrepTrim& trim15 = brep->NewTrim(brep->m_E[9], true, loop1562, 0 /* trim */); /* 16 */ trim15.m_iso = ON_Surface::S_iso; trim15.m_type = ON_BrepTrim::mated; trim15.m_tolerance[0] = SMALL_FASTF; trim15.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim56 = brep->NewTrim(brep->m_E[5], true, loop1562, 1 /* trim */); /* 17 */ trim56.m_iso = ON_Surface::E_iso; trim56.m_type = ON_BrepTrim::mated; trim56.m_tolerance[0] = SMALL_FASTF; trim56.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim62 = brep->NewTrim(brep->m_E[10], true, loop1562, 2 /* trim */); /* 18 */ trim62.m_iso = ON_Surface::N_iso; trim62.m_type = ON_BrepTrim::mated; trim62.m_tolerance[0] = SMALL_FASTF; trim62.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim21 = brep->NewTrim(brep->m_E[1], true, loop1562, 3 /* trim */); /* 19 */ trim21.m_iso = ON_Surface::W_iso; trim21.m_type = ON_BrepTrim::mated; trim21.m_tolerance[0] = SMALL_FASTF; trim21.m_tolerance[1] = SMALL_FASTF; ON_BrepFace& face0374 = brep->NewFace(5); ON_BrepLoop& loop0374 = brep->NewLoop(ON_BrepLoop::outer, face0374); /* 5 */ ON_BrepTrim& trim03 = brep->NewTrim(brep->m_E[3], true, loop0374, 0 /* trim */); /* 20 */ trim03.m_iso = ON_Surface::S_iso; trim03.m_type = ON_BrepTrim::mated; trim03.m_tolerance[0] = SMALL_FASTF; trim03.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim37 = brep->NewTrim(brep->m_E[11], true, loop0374, 1 /* trim */); /* 21 */ trim37.m_iso = ON_Surface::E_iso; trim37.m_type = ON_BrepTrim::mated; trim37.m_tolerance[0] = SMALL_FASTF; trim37.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim74 = brep->NewTrim(brep->m_E[7], true, loop0374, 2 /* trim */); /* 22 */ trim74.m_iso = ON_Surface::N_iso; trim74.m_type = ON_BrepTrim::mated; trim74.m_tolerance[0] = SMALL_FASTF; trim74.m_tolerance[1] = SMALL_FASTF; ON_BrepTrim& trim40 = brep->NewTrim(brep->m_E[8], true, loop0374, 3 /* trim */); /* 23 */ trim40.m_iso = ON_Surface::W_iso; trim40.m_type = ON_BrepTrim::mated; trim40.m_tolerance[0] = SMALL_FASTF; trim40.m_tolerance[1] = SMALL_FASTF; return brep; }
static int MakeTrimmingLoop( ON_Brep& brep, // returns index of loop ON_BrepFace& face, // face loop is on int v0, int v1, int v2, // Indices of corner vertices listed in A,B,C order int e0, // index of first edge int e0_dir, // orientation of edge int e1, // index second edgee int e1_dir, // orientation of edge int e2, // index third edge int e2_dir // orientation of edge ) { const ON_Surface& srf = *brep.m_S[face.m_si]; //Create new loop ON_BrepLoop& loop = brep.NewLoop( ON_BrepLoop::outer, face ); // Create trimming curves running counter clockwise. // Note that trims of outer loops run counter clockwise while trims of inner loops (holes) run clockwise. // Also note that when trims locate on surface N,S,E or W ends, then trim_iso becomes N_iso, S_iso, E_iso and W_iso respectfully. // While if trim is parallel to surface N,S or E,W, then trim is becomes y_iso and x_iso respectfully, the rest are not_iso. // Start at the south side ON_Curve* c2; int c2i, ei=0, bRev3d=0; ON_Surface::ISO iso = ON_Surface::not_iso; for ( int side = 0; side < 3; side++ ) { c2 = CreateTrimmingCurve( srf, side ); //Add trimming curve to brep trmming curves array c2i = brep.m_C2.Count(); brep.m_C2.Append(c2); switch ( side ) { case 0: // south ei = e0; bRev3d = (e0_dir == -1); iso = ON_Surface::S_iso; break; case 1: // diagonal ei = e1; bRev3d = (e1_dir == -1); iso = ON_Surface::not_iso; break; case 2: // diagonal ei = e2; bRev3d = (e2_dir == -1); iso = ON_Surface::not_iso; break; } //Create new trim topology that references edge, direction reletive to edge, loop and trim curve geometry ON_BrepTrim& trim = brep.NewTrim( brep.m_E[ei], bRev3d, loop, c2i ); trim.m_iso = iso; trim.m_type = ON_BrepTrim::boundary; // This one b-rep face, so all trims are boundary ones. trim.m_tolerance[0] = 0.0; // This simple example is exact - for models with non-exact trim.m_tolerance[1] = 0.0; // data, set tolerance as explained in definition of ON_BrepTrim. } return loop.m_loop_index; }
CRhinoCommand::result CCommandSampleUnrollSurface::RunCommand( const CRhinoCommandContext& context ) { CRhinoGetObject go; go.SetCommandPrompt( L"Select surface or polysurface to unroll" ); go.SetGeometryFilter( CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object ); go.EnableSubObjectSelect( FALSE ); go.GetObjects( 1, 1 ); if( go.CommandResult() != CRhinoCommand::success ) return go.CommandResult(); const CRhinoObject* pObject = go.Object(0).Object(); const ON_Brep* pBrep = go.Object(0).Brep(); if( 0 == pObject || 0 == pBrep ) return CRhinoCommand::failure; bool bExplode = false; ON_Brep* p3dBrep = 0; int i, type = -1; if(1 == pBrep->m_F.Count() ) { p3dBrep = pBrep->DuplicateFace( 0, false ); type = 0; } else { p3dBrep = static_cast<ON_Brep*>( pBrep->Duplicate() ); type = 1; } if( 0 == p3dBrep ) return CRhinoCommand::failure; p3dBrep->Compact(); for( i = 0; i < p3dBrep->m_F.Count(); i++ ) p3dBrep->RebuildEdges( p3dBrep->m_F[i], 0.00001, true, true ); p3dBrep->ShrinkSurfaces(); ReverseVReversedSurfaces( p3dBrep ); CRhinoUnroll Unroller( p3dBrep, context.m_doc.AbsoluteTolerance(), 0.1 ); int irc = Unroller.PrepareFaces(); if( 0 == irc ) { bool ok = Unroller.FlattenFaces(); if( ok ) { int flat_face_count = Unroller.CreateFlatBreps( bExplode, 2.0 ); if( flat_face_count ) { ON_SimpleArray<ON_Brep*> flat_breps; ON_ClassArray< ON_SimpleArray<ON_Curve*> > flat_curves; ON_ClassArray< ON_SimpleArray<ON_3dPoint> > flat_points; ON_ClassArray< ON_SimpleArray<ON_TextDot*> > flat_dots; Unroller.CollectResults( flat_breps, flat_curves, flat_points, flat_dots ); if( !bExplode && flat_breps.Count() > 1 ) { ON_Brep* pJoinedBrep = ON_Brep::New(); if( pJoinedBrep ) { for( i = 0; i < flat_breps.Count(); i++ ) { if( flat_breps[i] != 0 ) pJoinedBrep->Append( *flat_breps[i] ); } int joins = RhinoJoinBrepNakedEdges( *pJoinedBrep ); flat_breps.Empty(); flat_breps.Append( pJoinedBrep ); } } CRhinoObjectAttributes att = pObject->Attributes(); att.m_uuid = ON_nil_uuid; att.RemoveFromAllGroups(); for( i = 0; i < flat_breps.Count(); i++ ) { CRhinoBrepObject* flat_obj = new CRhinoBrepObject( att ); flat_obj->SetBrep( flat_breps[i] ); if( !context.m_doc.AddObject(flat_obj) ) delete flat_obj; // Don't leak... } } } delete p3dBrep; // Don't leak... } context.m_doc.Redraw(); return CRhinoCommand::success; }
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; }
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; }
int // return value not used? MakeTwistedCubeTrimmingLoop(ON_Brep& brep, ON_BrepFace& face, int v0, int v1, int v2, int v3, // indices of corner vertices int e0, int eo0, // edge index + orientation w.r.t surface trim int e1, int eo1, int e2, int eo2, int e3, int eo3) { // get a reference to the surface const ON_Surface& srf = *brep.m_S[face.m_si]; ON_BrepLoop& loop = brep.NewLoop(ON_BrepLoop::outer, face); // create the trimming curves running counter-clockwise around the // surface's domain, start at the south side ON_Curve* c2; int c2i, ei = 0, bRev3d = 0; ON_2dPoint q; // flags for isoparametric curves ON_Surface::ISO iso = ON_Surface::not_iso; for (int side = 0; side < 4; side++) { // side: 0=south, 1=east, 2=north, 3=west c2 = TwistedCubeTrimmingCurve( srf, side ); c2i = brep.m_C2.Count(); brep.m_C2.Append(c2); switch (side) { case 0: ei = e0; bRev3d = (eo0 == -1); iso = ON_Surface::S_iso; break; case 1: ei = e1; bRev3d = (eo1 == -1); iso = ON_Surface::E_iso; break; case 2: ei = e2; bRev3d = (eo2 == -1); iso = ON_Surface::N_iso; break; case 3: ei = e3; bRev3d = (eo3 == -1); iso = ON_Surface::W_iso; break; } ON_BrepTrim& trim = brep.NewTrim(brep.m_E[ei], bRev3d, loop, c2i); trim.m_iso = iso; // the type gives metadata on the trim type in this case, "mated" // means the trim is connected to an edge, is part of an // outer/inner/slit loop, no other trim from the same edge is // connected to the edge, and at least one trim from a different // loop is connected to the edge trim.m_type = ON_BrepTrim::mated; // i.e. this b-rep is closed, so // all trims have mates // not convinced these shouldn't be set with a member function trim.m_tolerance[0] = 0.0; // exact trim.m_tolerance[1] = 0.0; // } return loop.m_loop_index; }