////////// // Create an circle from two 2d points and a tangent at the first point. bool ON_Circle::Create( const ON_2dPoint& P, // [IN] point P const ON_2dVector& Pdir, // [IN] tangent at P const ON_2dPoint& Q // [IN] point Q ) { return Create( ON_3dPoint(P), ON_3dVector(Pdir), ON_3dPoint(Q) ); }
////////// // Create an arc from a 2d start point, 2d start direction, and 2d end point. bool ON_Arc::Create( const ON_2dPoint& P, // [IN] start point const ON_2dVector& Pdir, // [IN] arc direction at start const ON_2dPoint& Q // [IN] end point ) { return Create( ON_3dPoint(P), ON_3dVector(Pdir), ON_3dPoint(Q) ); }
bool ON_Circle::Create( // circle through three 3d points const ON_2dPoint& P, const ON_2dPoint& Q, const ON_2dPoint& R ) { return Create(ON_3dPoint(P),ON_3dPoint(Q),ON_3dPoint(R)); }
RH_C_FUNCTION void ON_Light_SetLocation(ON_Light* pLight, ON_3DPOINT_STRUCT loc) { if( pLight ) { pLight->SetLocation(ON_3dPoint(loc.val[0], loc.val[1], loc.val[2])); } }
void CMeshDirDrawCallback::DrawMiddleground( CRhinoViewport& vp, CRhinoDoc& ) { int mi, mcnt, fi, fcnt, vi, vcnt; mcnt = m_mesh_list.Count(); for( mi = 0; mi < mcnt; mi++ ) { ON_Color saved_color = vp.DrawColor(); CMeshDir& md = m_mesh_list[mi]; if( m_draw_face_normals ) { fcnt = md.m_face_center.Count(); vp.SetDrawColor( m_face_normal_color ); for( fi = 0; fi < fcnt; fi++ ) { vp.DrawDirectionArrow( md.m_face_center[fi], md.m_face_normal[fi] ); } } if( m_draw_vertex_normals ) { if ( md.m_mesh->HasVertexNormals() ) { vp.SetDrawColor( m_vertex_normal_color ); vcnt = md.m_mesh->m_V.Count(); for( vi = 0; vi < vcnt; vi++ ) { vp.DrawDirectionArrow( ON_3dPoint(md.m_mesh->m_V[vi]), ON_3dVector(md.m_mesh->m_N[vi]) ); } } } vp.SetDrawColor( saved_color ); } }
ON_BOOL32 ON_InstanceRef::GetBBox( double* boxmin, double* boxmax, ON_BOOL32 bGrowBox ) const { if ( !boxmin || !boxmax ) { bGrowBox = false; } else if ( bGrowBox ) { bGrowBox = ON_BoundingBox(ON_3dPoint(boxmin),ON_3dPoint(boxmax)).IsValid(); } if( m_bbox.IsValid() ) { if( bGrowBox ) { if( boxmin[0] > m_bbox.m_min.x ) boxmin[0] = m_bbox.m_min.x; if( boxmin[1] > m_bbox.m_min.y ) boxmin[1] = m_bbox.m_min.y; if( boxmin[2] > m_bbox.m_min.z ) boxmin[2] = m_bbox.m_min.z; if( boxmax[0] < m_bbox.m_max.x ) boxmax[0] = m_bbox.m_max.x; if( boxmax[1] < m_bbox.m_max.y ) boxmax[1] = m_bbox.m_max.y; if( boxmax[2] < m_bbox.m_max.z ) boxmax[2] = m_bbox.m_max.z; } else { if( boxmin ) { boxmin[0] = m_bbox.m_min.x; boxmin[1] = m_bbox.m_min.y; boxmin[2] = m_bbox.m_min.z; } if( boxmax ) { boxmax[0] = m_bbox.m_max.x; boxmax[1] = m_bbox.m_max.y; boxmax[2] = m_bbox.m_max.z; } bGrowBox = true; } } return bGrowBox; }
ON_4dPoint ON_SpaceMorph::MorphPoint( ON_4dPoint point ) const { ON_4dPoint q = MorphPoint(ON_3dPoint(point)); q.w = point.w; q.x *= q.w; q.y *= q.w; q.z *= q.w; return q; }
RH_C_FUNCTION int ON_PointCloud_GetClosestPoint(const ON_PointCloud* pConstPointCloud, ON_3DPOINT_STRUCT point) { int rc = -1; if( pConstPointCloud ) { int index = -1; if( pConstPointCloud->GetClosestPoint( ON_3dPoint(point.val), &index) ) rc = index; } return rc; }
ON_3dPoint ON_Line::PointAt( double t ) const { // 26 Feb 2003 Dale Lear // Changed // return (1-t)*from + t*to; // to the following so that axis aligned lines will // return exact answers for large values of t. // See RR 9683. const double s = 1.0-t; return ON_3dPoint( (from.x == to.x) ? from.x : s*from.x + t*to.x, (from.y == to.y) ? from.y : s*from.y + t*to.y, (from.z == to.z) ? from.z : s*from.z + t*to.z ); }
void mesh_info_init(struct rt_bot_internal *bot, struct Mesh_Info *mesh) { for (size_t i = 0; i < bot->num_vertices; ++i) { mesh->points_p0.Append(ON_3dPoint(&bot->vertices[i*3])); mesh->iteration_of_insert[i] = 0; } for (size_t i = 0; i < bot->num_faces; ++i) { mesh_add_face(bot->faces[i*3+0], bot->faces[i*3+1], bot->faces[i*3+2], i, mesh); } mesh->iteration_cnt = 0; }
/** * Intersect two meshes and returns their intersection in Polylines * (ON_3dPoint arrays). Returns how many polylines where found 0 * indicates no intersection or -1 on error. */ int MeshMeshIntersect( ON_Mesh *mesh1, ON_Mesh *mesh2, double tol ) { /* First both meshes need to be triangulated */ MeshTriangulate(mesh1); MeshTriangulate(mesh2); int i, j; for (i = 0; i < mesh1->FaceCount(); i++) { ON_MeshFace face1 = mesh1->m_F[i]; for (j = 0; j < mesh2->FaceCount(); j++) { ON_MeshFace face2 = mesh2->m_F[j]; ON_3dPoint result[6]; char edge[6]; int rv = TriangleTriangleIntersect(ON_3dPoint(mesh1->m_V[face1.vi[0]]), ON_3dPoint(mesh1->m_V[face1.vi[1]]), ON_3dPoint(mesh1->m_V[face1.vi[2]]), ON_3dPoint(mesh2->m_V[face2.vi[0]]), ON_3dPoint(mesh2->m_V[face2.vi[1]]), ON_3dPoint(mesh2->m_V[face2.vi[2]]), result, edge, tol); if (rv == 2) { } } } return 0; }
void ON_Light::Default() { m_light_name.Destroy(); m_bOn = 1; m_intensity = 1.0; m_watts = 0.0; m_style = ON::camera_directional_light; m_ambient = ON_Color(0,0,0); m_diffuse = ON_Color(255,255,255); m_specular = ON_Color(255,255,255); m_direction = ON_3dVector(0.0,0.0,-1.0); m_location = ON_3dPoint(0.0,0.0,0.0); m_length = ON_3dVector(0.0,0.0,0.0); m_width = ON_3dVector(0.0,0.0,0.0); m_spot_angle = 180.0; m_spot_exponent = 0.0; m_hotspot = 1.0; m_attenuation = ON_3dVector(1.0,0.0,0.0); m_shadow_intensity = 1.0; m_light_index = 0; memset(&m_light_id,0,sizeof(m_light_id)); }
// From Kobbelt sqrt(3)-Subdivision, eqns 7 and 8, solving for pinf void point_inf(size_t p, struct Mesh_Info *mesh, ON_3dPointArray *p_a) { size_t n = mesh->point_valence[p]; std::multimap<size_t, size_t>::iterator p_it; std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> range; range = mesh->point_neighbors.equal_range(p); ON_3dPoint psum = ON_3dPoint(0, 0, 0); for (p_it = range.first; p_it != range.second; p_it++) { psum = psum + *mesh->points_p0.At((int)(*p_it).second); } fastf_t alpha = alpha_n(n); // // 3 an 1 // [pinf = ---------- * psum + -------- * p0] // 3 an n + n 3 an + 1 // ON_3dPoint pinf = (3*alpha/((3*alpha+1)*n))*psum + 1/(3*alpha+1) * *mesh->points_p0.At((int)p); p_a->Append(pinf); }
extern "C" void rt_nmg_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol) { struct model *m; struct nmgregion *r; struct shell *s; struct faceuse *fu; struct loopuse *lu; struct edgeuse *eu; int edge_index; long* brepi; RT_CK_DB_INTERNAL(ip); m = (struct model *)ip->idb_ptr; NMG_CK_MODEL(m); brepi = static_cast<long*>(bu_malloc(m->maxindex * sizeof(long), "rt_nmg_brep: brepi[]")); for (int i = 0; i < m->maxindex; i++) brepi[i] = -INT_MAX; for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) { for (BU_LIST_FOR(s, shell, &r->s_hd)) { for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) { NMG_CK_FACEUSE(fu); if (fu->orientation != OT_SAME) continue; // Need to create ON_NurbsSurface based on plane of // face in order to have UV space in which to define // trimming loops. Bounding points are NOT on the // face plane, so another approach must be used. // // General approach: For all loops in the faceuse, // collect all the vertices. Find the center point of // all the vertices, and search for the point with the // greatest distance from that center point. Once // found, cross the vector between the center point // and furthest point with the normal of the face and // scale the resulting vector to have the same length // as the vector to the furthest point. Add the two // resulting vectors to find the first corner point. // Mirror the first corner point across the center to // find the second corner point. Cross the two // vectors created by the first two corner points with // the face normal to get the vectors of the other two // corners, and scale the resulting vectors to the // same magnitude as the first two. These four points // bound all vertices on the plane and form a suitable // staring point for a UV space, since all points on // all the edges are equal to or further than the // distance between the furthest vertex and the center // point. // ............. ............. // . .* . . // . . . . . // . . . . . // . . . * . // . . . . . // . . . . . // . . . . . // . * * . . // . . . . // . . . . // . . . . // . *. . . // . ... ...* . // . .... .... . // . * . // ........................... // const struct face_g_plane *fg = fu->f_p->g.plane_p; struct bu_ptbl vert_table; nmg_tabulate_face_g_verts(&vert_table, fg); point_t tmppt, center, max_pt; struct vertex **pt; VSET(tmppt, 0, 0, 0); VSET(max_pt, 0, 0, 0); int ptcnt = 0; for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) { tmppt[0] += (*pt)->vg_p->coord[0]; tmppt[1] += (*pt)->vg_p->coord[1]; tmppt[2] += (*pt)->vg_p->coord[2]; ptcnt++; if (brepi[(*pt)->vg_p->index] == -INT_MAX) { ON_BrepVertex& vert = (*b)->NewVertex((*pt)->vg_p->coord, SMALL_FASTF); brepi[(*pt)->vg_p->index] = vert.m_vertex_index; } } VSET(center, tmppt[0]/ptcnt, tmppt[1]/ptcnt, tmppt[2]/ptcnt); fastf_t max_dist = 0.0; fastf_t curr_dist; for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) { tmppt[0] = (*pt)->vg_p->coord[0]; tmppt[1] = (*pt)->vg_p->coord[1]; tmppt[2] = (*pt)->vg_p->coord[2]; curr_dist = DIST_PT_PT(center, tmppt); if (curr_dist > max_dist) { max_dist = curr_dist; VMOVE(max_pt, tmppt); } } bu_ptbl_free(&vert_table); int ccw = 0; vect_t vtmp, uv1, uv2, uv3, uv4, vnormal; // If an outer loop is found in the nmg with a cw // orientation, use a flipped normal to form the NURBS // surface for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) { if (lu->orientation == OT_SAME && nmg_loop_is_ccw(lu, fg->N, tol) == -1) ccw = -1; } if (ccw != -1) { VSET(vnormal, fg->N[0], fg->N[1], fg->N[2]); } else { VSET(vnormal, -fg->N[0], -fg->N[1], -fg->N[2]); } VSUB2(uv1, max_pt, center); VCROSS(vtmp, uv1, vnormal); VADD2(uv1, uv1, vtmp); VCROSS(uv2, uv1, vnormal); VREVERSE(uv3, uv1); VCROSS(uv4, uv3, vnormal); VADD2(uv1, uv1, center); VADD2(uv2, uv2, center); VADD2(uv3, uv3, center); VADD2(uv4, uv4, center); ON_3dPoint p1 = ON_3dPoint(uv1); ON_3dPoint p2 = ON_3dPoint(uv2); ON_3dPoint p3 = ON_3dPoint(uv3); ON_3dPoint p4 = ON_3dPoint(uv4); (*b)->m_S.Append(sideSurface(p1, p4, p3, p2)); ON_Surface *surf = (*(*b)->m_S.Last()); int surfindex = (*b)->m_S.Count(); // Now that we have the surface, define the face ON_BrepFace& face = (*b)->NewFace(surfindex - 1); // With the surface and the face defined, make // trimming loops and create faces. To generate UV // coordinates for each from and to for the // edgecurves, the UV origin is defined to be v1, // v1->v2 is defined as the U domain, and v1->v4 is // defined as the V domain. vect_t u_axis, v_axis; VSUB2(u_axis, uv2, uv1); VSUB2(v_axis, uv4, uv1); fastf_t u_axis_dist = MAGNITUDE(u_axis); fastf_t v_axis_dist = MAGNITUDE(v_axis); // Now that the surface context is set up, add the loops. for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) { int edges=0; if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) continue; // loop is a single vertex ON_BrepLoop::TYPE looptype; // Check if this is an inner or outer loop if (lu->orientation == OT_SAME) { looptype = ON_BrepLoop::outer; } else { looptype = ON_BrepLoop::inner; } ON_BrepLoop& loop = (*b)->NewLoop(looptype, face); for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) { ++edges; vect_t ev1, ev2; struct vertex_g *vg1, *vg2; vg1 = eu->vu_p->v_p->vg_p; NMG_CK_VERTEX_G(vg1); int vert1 = brepi[vg1->index]; VMOVE(ev1, vg1->coord); vg2 = eu->eumate_p->vu_p->v_p->vg_p; NMG_CK_VERTEX_G(vg2); int vert2 = brepi[vg2->index]; VMOVE(ev2, vg2->coord); // Add edge if not already added if (brepi[eu->e_p->index] == -INT_MAX) { /* always add edges with the small vertex index as from */ if (vg1->index > vg2->index) { int tmpvert = vert1; vert1 = vert2; vert2 = tmpvert; } // Create and add 3D curve ON_Curve* c3d = new ON_LineCurve((*b)->m_V[vert1].Point(), (*b)->m_V[vert2].Point()); c3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(c3d); // Create and add 3D edge ON_BrepEdge& e = (*b)->NewEdge((*b)->m_V[vert1], (*b)->m_V[vert2] , (*b)->m_C3.Count() - 1); e.m_tolerance = 0.0; brepi[eu->e_p->index] = e.m_edge_index; } // Regardless of whether the edge existed as // an object, it needs to be added to the // trimming loop vect_t u_component, v_component; ON_3dPoint vg1pt(vg1->coord); int orientation = 0; edge_index = brepi[eu->e_p->index]; if (vg1pt != (*b)->m_V[(*b)->m_E[edge_index].m_vi[0]].Point()) { orientation = 1; } // Now, make 2d trimming curves vect_t vect1, vect2; VSUB2(vect1, ev1, uv1); VSUB2(vect2, ev2, uv1); ON_2dPoint from_uv, to_uv; double u0, u1, v0, v1; surf->GetDomain(0, &u0, &u1); surf->GetDomain(1, &v0, &v1); VPROJECT(vect1, u_axis, u_component, v_component); from_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0); from_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0); VPROJECT(vect2, u_axis, u_component, v_component); to_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0); to_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0); ON_3dPoint S1, S2; ON_3dVector Su, Sv; surf->Ev1Der(from_uv.x, from_uv.y, S1, Su, Sv); surf->Ev1Der(to_uv.x, to_uv.y, S2, Su, Sv); ON_Curve* c2d = new ON_LineCurve(from_uv, to_uv); c2d->SetDomain(0.0, 1.0); int c2i = (*b)->m_C2.Count(); (*b)->m_C2.Append(c2d); edge_index = brepi[eu->e_p->index]; ON_BrepTrim& trim = (*b)->NewTrim((*b)->m_E[edge_index], orientation, loop, c2i); trim.m_type = ON_BrepTrim::mated; trim.m_tolerance[0] = 0.0; trim.m_tolerance[1] = 0.0; } } } (*b)->SetTrimIsoFlags(); } } bu_free(brepi, "rt_nmg_brep: brepi[]"); }
HIDDEN int nmg_brep_face(ON_Brep **b, const struct faceuse *fu, const struct bn_tol *tol, long *brepi) { const struct face_g_plane *fg = fu->f_p->g.plane_p; struct bu_ptbl vert_table; struct vertex **pt; int ret = 0; int pnt_cnt = 0; int pnt_index = 0; vect_t u_axis, v_axis; point_t obr_center; point_t *points_3d = NULL; point_t *points_obr = NULL; struct loopuse *lu; struct edgeuse *eu; /* Find out how many points we have, set up any uninitialized ON_Brep vertex * structures, and prepare a map of NMG index values to the point array indices */ nmg_tabulate_face_g_verts(&vert_table, fg); for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) { if (brepi[(*pt)->vg_p->index] == -INT_MAX) { ON_BrepVertex& vert = (*b)->NewVertex((*pt)->vg_p->coord, SMALL_FASTF); brepi[(*pt)->vg_p->index] = vert.m_vertex_index; } pnt_cnt++; } /* Prepare the 3D obr input array */ points_3d = (point_t *)bu_calloc(pnt_cnt + 1, sizeof(point_t), "nmg points"); for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) { VSET(points_3d[pnt_index], (*pt)->vg_p->coord[0],(*pt)->vg_p->coord[1],(*pt)->vg_p->coord[2]); pnt_index++; } bu_ptbl_free(&vert_table); /* Calculate the 3D coplanar oriented bounding rectangle (obr) */ ret += bg_3d_coplanar_obr(&obr_center, &u_axis, &v_axis, (const point_t *)points_3d, pnt_cnt); if (ret) { bu_log("Failed to get oriented bounding rectangle for NMG faceuse #%lu\n", fu->index); return -1; } bu_free(points_3d, "done with obr 3d point inputs"); /* Use the obr to define the 3D corner points of the NURBS surface */ points_obr = (point_t *)bu_calloc(3 + 1, sizeof(point_t), "points_3d"); VADD3(points_obr[2], obr_center, u_axis, v_axis); VSCALE(u_axis, u_axis, -1); VADD3(points_obr[3], obr_center, u_axis, v_axis); VSCALE(v_axis, v_axis, -1); VADD3(points_obr[0], obr_center, u_axis, v_axis); VSCALE(u_axis, u_axis, -1); VADD3(points_obr[1], obr_center, u_axis, v_axis); /* We need to orient our surface correctly according to the NMG - using * the openNURBS FlipFace function later does not seem to work very * well. If an outer loop is found in the NMG with a cw orientation, * factor that in in addition to the fu->f_p->flip flag. */ int ccw = 0; vect_t vtmp, uv1, uv2, vnormal; point_t center; VADD2(center, points_obr[0], points_obr[1]); VADD2(center, center, points_obr[2]); VADD2(center, center, points_obr[3]); VSCALE(center, center, 0.25); for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) { if (lu->orientation == OT_SAME && nmg_loop_is_ccw(lu, fg->N, tol) == -1) ccw = -1; } if (ccw != -1) { VSET(vnormal, fg->N[0], fg->N[1], fg->N[2]); } else { VSET(vnormal, -fg->N[0], -fg->N[1], -fg->N[2]); } if (fu->f_p->flip) VSET(vnormal, -vnormal[0], -vnormal[1], -vnormal[2]); VSUB2(uv1, points_obr[0], center); VSUB2(uv2, points_obr[1], center); VCROSS(vtmp, uv1, uv2); if (VDOT(vtmp, vnormal) < 0) { VMOVE(vtmp, points_obr[0]); VMOVE(points_obr[0], points_obr[1]); VMOVE(points_obr[1], vtmp); VMOVE(vtmp, points_obr[3]); VMOVE(points_obr[3], points_obr[2]); VMOVE(points_obr[2], vtmp); } /* Now that we've got our points correctly oriented for * the NURBS surface, proceed to create it. */ ON_3dPoint p1 = ON_3dPoint(points_obr[0]); ON_3dPoint p2 = ON_3dPoint(points_obr[1]); ON_3dPoint p3 = ON_3dPoint(points_obr[2]); ON_3dPoint p4 = ON_3dPoint(points_obr[3]); (*b)->m_S.Append(sideSurface(p1, p2, p3, p4)); ON_Surface *surf = (*(*b)->m_S.Last()); int surfindex = (*b)->m_S.Count(); ON_BrepFace& face = (*b)->NewFace(surfindex - 1); // With the surface and the face defined, make // trimming loops and create faces. To generate UV // coordinates for each from and to for the // edgecurves, the UV origin is defined to be v1, // v1->v2 is defined as the U domain, and v1->v4 is // defined as the V domain. VSUB2(u_axis, points_obr[2], points_obr[1]); VSUB2(v_axis, points_obr[0], points_obr[1]); fastf_t u_axis_dist = MAGNITUDE(u_axis); fastf_t v_axis_dist = MAGNITUDE(v_axis); /* Now that we have the surface and the face, add the loops */ for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) { if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) continue; // loop is a single vertex // Check if this is an inner or outer loop ON_BrepLoop::TYPE looptype = (lu->orientation == OT_SAME) ? ON_BrepLoop::outer : ON_BrepLoop::inner; ON_BrepLoop& loop = (*b)->NewLoop(looptype, face); for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) { vect_t ev1, ev2; struct vertex_g *vg1 = eu->vu_p->v_p->vg_p; struct vertex_g *vg2 = eu->eumate_p->vu_p->v_p->vg_p; NMG_CK_VERTEX_G(vg1); NMG_CK_VERTEX_G(vg2); VMOVE(ev1, vg1->coord); VMOVE(ev2, vg2->coord); // Add edge if not already added if (brepi[eu->e_p->index] == -INT_MAX) { /* always add edges with the small vertex index as from */ int vert1 = (vg1->index <= vg2->index) ? brepi[vg1->index] : brepi[vg2->index]; int vert2 = (vg1->index > vg2->index) ? brepi[vg1->index] : brepi[vg2->index]; // Create and add 3D curve ON_Curve* c3d = new ON_LineCurve((*b)->m_V[vert1].Point(), (*b)->m_V[vert2].Point()); c3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(c3d); // Create and add 3D edge ON_BrepEdge& e = (*b)->NewEdge((*b)->m_V[vert1], (*b)->m_V[vert2] , (*b)->m_C3.Count() - 1); e.m_tolerance = 0.0; brepi[eu->e_p->index] = e.m_edge_index; } // Regardless of whether the edge existed as an object, it needs to be added to the trimming loop ON_3dPoint vg1pt(vg1->coord); int orientation = ((vg1pt != (*b)->m_V[(*b)->m_E[(int)brepi[eu->e_p->index]].m_vi[0]].Point())) ? 1 : 0; // Make a 2d trimming curve, create a trim, and add the trim to the loop vect_t vect1, vect2, u_component, v_component; double u0, u1, v0, v1; ON_2dPoint from_uv, to_uv; VSUB2(vect1, ev1, points_obr[0]); VSUB2(vect2, ev2, points_obr[0]); surf->GetDomain(0, &u0, &u1); surf->GetDomain(1, &v0, &v1); VPROJECT(vect1, u_axis, u_component, v_component); from_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0); from_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0); VPROJECT(vect2, u_axis, u_component, v_component); to_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0); to_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0); ON_Curve* c2d = new ON_LineCurve(from_uv, to_uv); c2d->SetDomain(0.0, 1.0); int c2i = (*b)->m_C2.Count(); (*b)->m_C2.Append(c2d); ON_BrepTrim& trim = (*b)->NewTrim((*b)->m_E[(int)brepi[eu->e_p->index]], orientation, loop, c2i); trim.m_type = ON_BrepTrim::mated; trim.m_tolerance[0] = 0.0; trim.m_tolerance[1] = 0.0; } } bu_free(points_obr, "Done with obr"); return 0; }
// // Copyright (c) 1993-2007 Robert McNeel & Associates. All rights reserved. // Rhinoceros is a registered trademark of Robert McNeel & Assoicates. // // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF // MERCHANTABILITY ARE HEREBY DISCLAIMED. // // For complete openNURBS copyright information see <http://www.opennurbs.org>. // //////////////////////////////////////////////////////////////// */ #include "opennurbs.h" const ON_Plane ON_xy_plane( ON_3dPoint(0.0,0.0,0.0), ON_3dVector(1.0,0.0,0.0), ON_3dVector(0.0,1.0,0.0) ); const ON_Plane ON_yz_plane( ON_3dPoint(0.0,0.0,0.0), ON_3dVector(0.0,1.0,0.0), ON_3dVector(0.0,0.0,1.0) ); const ON_Plane ON_zx_plane( ON_3dPoint(0.0,0.0,0.0), ON_3dVector(0.0,0.0,1.0), ON_3dVector(1.0,0.0,0.0) ); const ON_Plane ON_Plane::World_xy=ON_xy_plane;
extern "C" void rt_sketch_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *UNUSED(tol)) { struct rt_sketch_internal *eip; RT_CK_DB_INTERNAL(ip); eip = (struct rt_sketch_internal *)ip->idb_ptr; RT_SKETCH_CK_MAGIC(eip); ON_3dPoint plane_origin; ON_3dVector plane_x_dir, plane_y_dir; // Find plane in 3 space corresponding to the sketch. plane_origin = ON_3dPoint(eip->V); plane_x_dir = ON_3dVector(eip->u_vec); plane_y_dir = ON_3dVector(eip->v_vec); const ON_Plane sketch_plane = ON_Plane(plane_origin, plane_x_dir, plane_y_dir); // For the brep, need the list of 3D vertex points. In sketch, they // are stored as 2D coordinates, so use the sketch_plane to define 3 space // points for the vertices. for (size_t i = 0; i < eip->vert_count; i++) { (*b)->NewVertex(sketch_plane.PointAt(eip->verts[i][0], eip->verts[i][1]), 0.0); } // Create the brep elements corresponding to the sketch lines, curves // and bezier segments. Create 2d, 3d and BrepEdge elements for each segment. // Will need to use the bboxes of each element to // build the overall bounding box for the face. Use bGrowBox to expand // a single box. struct line_seg *lsg; struct carc_seg *csg; struct bezier_seg *bsg; uint32_t *lng; for (size_t i = 0; i < (&eip->curve)->count; i++) { lng = (uint32_t *)(&eip->curve)->segment[i]; switch (*lng) { case CURVE_LSEG_MAGIC: { lsg = (struct line_seg *)lng; ON_Curve* lsg3d = new ON_LineCurve((*b)->m_V[lsg->start].Point(), (*b)->m_V[lsg->end].Point()); lsg3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(lsg3d); } break; case CURVE_CARC_MAGIC: csg = (struct carc_seg *)lng; if (csg->radius < 0) { ON_3dPoint cntrpt = (*b)->m_V[csg->end].Point(); ON_3dPoint edgept = (*b)->m_V[csg->start].Point(); ON_Plane cplane = ON_Plane(cntrpt, plane_x_dir, plane_y_dir); ON_Circle c3dcirc = ON_Circle(cplane, cntrpt.DistanceTo(edgept)); ON_Curve* c3d = new ON_ArcCurve((const ON_Circle)c3dcirc); c3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(c3d); } else { // need to calculated 3rd point on arc - look to sketch.c around line 581 for // logic } break; case CURVE_BEZIER_MAGIC: bsg = (struct bezier_seg *)lng; { ON_3dPointArray bezpoints(bsg->degree + 1); for (int j = 0; j < bsg->degree + 1; j++) { bezpoints.Append((*b)->m_V[bsg->ctl_points[j]].Point()); } ON_BezierCurve bez3d = ON_BezierCurve((const ON_3dPointArray)bezpoints); ON_NurbsCurve* beznurb3d = ON_NurbsCurve::New(); bez3d.GetNurbForm(*beznurb3d); beznurb3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(beznurb3d); } break; default: bu_log("Unhandled sketch object\n"); break; } } // Create the plane surface and brep face. ON_PlaneSurface *sketch_surf = new ON_PlaneSurface(sketch_plane); (*b)->m_S.Append(sketch_surf); int surfindex = (*b)->m_S.Count(); ON_BrepFace& face = (*b)->NewFace(surfindex - 1); // For the purposes of BREP creation, it is necessary to identify // loops created by sketch segments. This information is not stored // in the sketch data structures themselves, and thus must be deduced FindLoops(b); const ON_BrepLoop* tloop = (*b)->m_L.First(); sketch_surf->SetDomain(0, tloop->m_pbox.m_min.x, tloop->m_pbox.m_max.x); sketch_surf->SetDomain(1, tloop->m_pbox.m_min.y, tloop->m_pbox.m_max.y); sketch_surf->SetExtents(0, sketch_surf->Domain(0)); sketch_surf->SetExtents(1, sketch_surf->Domain(1)); (*b)->SetTrimIsoFlags(face); (*b)->FlipFace(face); (*b)->Compact(); }
CRhinoCommand::result CGenCylinder::RunCommand( const CRhinoCommandContext& context ) { Cscript1PlugIn& plugin = script1PlugIn(); if( !plugin.IsDlgVisible() ) { return CRhinoCommand::nothing; } /*****************************************/ /*CHECKING IF THERE IS ALREADY A CYLINDER*/ /*****************************************/ const CRhinoLayer& layer = context.m_doc.m_layer_table.CurrentLayer(); ON_SimpleArray<CRhinoObject*> objects; int object_count = context.m_doc.LookupObject( layer, objects ); const CRhinoBrepObject* brep_obj; const CRhinoCurveObject* curve_obj; const CRhinoSurfaceObject* surface_obj; int surf_count=0; if( object_count > 0 ) { int brep_obj_count = 0; int polycurve_count = 0; const CRhinoObject* object = 0; for(int i = 0; i < object_count; i++ ) { object = objects[ i ]; /************************************/ /*TRY CASTING AS A RHINO BREP OBJECT*/ /************************************/ brep_obj = CRhinoBrepObject::Cast( object ); if( brep_obj && object->IsSolid()) { brep_obj_count++; } /*******************************/ /*TRY CASTING AS A CURVE OBJECT*/ /*******************************/ curve_obj = CRhinoCurveObject::Cast( object ); if( curve_obj ) { polycurve_count++; } //surface_obj = CRhinoSurfaceObject::Cast( object ); // if( surface_obj ) // { //surf_count++; // } } if( brep_obj_count == 0) { ON_3dPoint center_point( 0.0, 0.0, 0.0 ); double radius = 63.5; int __count = plugin.m_dialog->m_comboAltTacco.GetCount(); int nIndex = plugin.m_dialog->m_comboAltTacco.GetCurSel(); CString strCBText; plugin.m_dialog->m_comboAltTacco.GetLBText( nIndex, strCBText); int height = _wtoi(strCBText); ON_3dPoint height_point( 0.0, 0.0, height); ON_3dVector zaxis = height_point - center_point; ON_Plane planeCir( center_point, zaxis ); /*ADD CIRCLE FOR CYLINDER'S BASE*/ ON_Circle circle( planeCir, radius ); /*ADD CYLINDER*/ ON_Cylinder cylinder( circle, zaxis.Length() ); ON_Brep* brep = ON_BrepCylinder( cylinder, TRUE, TRUE ); unsigned int first_SN; unsigned int next_SN; if( brep ) { first_SN = CRhinoObject::NextRuntimeObjectSerialNumber(); /********************/ /*TRANSLATE CYLINDER*/ /********************/ int nIndex1 = plugin.m_dialog->AltezzaFondelloControllo.GetCurSel(); CString strCBText1; plugin.m_dialog->AltezzaFondelloControllo.GetLBText( nIndex1, strCBText1); int altfondello = _wtoi(strCBText1); ON_wString obj_nameCyl = L"CILINDRO"; brep->Translate(ON_3dVector( 0.0, 0.0, -altfondello)); CRhinoBrepObject* cylinder_object = new CRhinoBrepObject(); cylinder_object->SetBrep( brep ); if( context.m_doc.AddObject(cylinder_object) ) { context.m_doc.Redraw(); next_SN = CRhinoObject::NextRuntimeObjectSerialNumber(); if( first_SN == next_SN ) { return CRhinoCommand::nothing; } else { SetNametoObject(context.m_doc,first_SN,obj_nameCyl,true); } } else { delete cylinder_object; } /*********************************************/ /* DA SISTEMARE */ /*********************************************/ CRhinoSnapContext snap; bool dec1 = snap.SnapToPoint(ON_3dPoint(63.5, 0.0, (height - altfondello))); bool dec2 = snap.SnapToPoint(ON_3dPoint(63.5, 0.0, -altfondello)); bool dec3 = snap.SnapToPoint(ON_3dPoint(63.5, 0.0, 0.0)); if(dec1 && dec2) { CRhinoLinearDimension* dim_obj = new CRhinoLinearDimension(); ON_Plane plane( ON_zx_plane ); plane.SetOrigin( ON_3dPoint(63.5, 0.0, 0.0) ); dim_obj->SetPlane( plane ); ON_3dPoint pt_1(63.5, 0.0, (height - altfondello)); ON_3dPoint pt_2(63.5, 0.0, -altfondello); double u, v; plane.ClosestPointTo( pt_1, &u, &v ); dim_obj->SetPoint( 0, ON_2dPoint(u, v) ); dim_obj->SetPoint( 1, ON_2dPoint(u, (v + height/2)) ); plane.ClosestPointTo( pt_2, &u, &v ); dim_obj->SetPoint( 2, ON_2dPoint(u, v) ); dim_obj->SetPoint( 3, ON_2dPoint(u, (v + height/2)) ); dim_obj->UpdateText(); if( context.m_doc.AddObject(dim_obj) ) { context.m_doc.Redraw(); } else { delete dim_obj; } } /*********************************************/ /* DA SISTEMARE */ /*********************************************/ if(dec2 && dec3) { CRhinoLinearDimension* dim_obj = new CRhinoLinearDimension(); ON_Plane plane( ON_zx_plane ); plane.SetOrigin( ON_3dPoint(63.5, 0.0, 0.0) ); dim_obj->SetPlane( plane ); ON_3dPoint pt_1(63.5, 0.0, 0.0); ON_3dPoint pt_2(63.5, 0.0, -altfondello); double u, v; plane.ClosestPointTo( pt_1, &u, &v ); dim_obj->SetPoint( 0, ON_2dPoint(u, v) ); dim_obj->SetPoint( 1, ON_2dPoint(u, (v + height/2)) ); plane.ClosestPointTo( pt_2, &u, &v ); dim_obj->SetPoint( 2, ON_2dPoint(u, v) ); dim_obj->SetPoint( 3, ON_2dPoint(u, (v + height/2)) ); dim_obj->UpdateText(); if( context.m_doc.AddObject(dim_obj) ) { context.m_doc.Redraw(); } else { delete dim_obj; } } /*********************************************/ /* DA SISTEMARE By Nello */ /*********************************************/ ON_3dPoint provapunto2 = AltezzaTacco; ON_3dPoint provapunto(59.5,0,provapunto2.z); provapunto.z-=0.7; ON_3dPoint pt_1(59.5, 0.0, (height - altfondello)); CRhinoLinearDimension* dim_obj = new CRhinoLinearDimension(); ON_Plane plane( ON_zx_plane ); plane.SetOrigin(pt_1); dim_obj->SetPlane( plane ); //ON_3dPoint pt_1(63.5, 0.0, 0.0); ON_3dPoint pt_2 = provapunto; double u, v; plane.ClosestPointTo( pt_1, &u, &v ); dim_obj->SetPoint( 0, ON_2dPoint(u, v) ); dim_obj->SetPoint( 1, ON_2dPoint(u, (v + height/2)) ); plane.ClosestPointTo( pt_2, &u, &v ); dim_obj->SetPoint( 2, ON_2dPoint(u, v) ); dim_obj->SetPoint( 3, ON_2dPoint(u, (v + height/2)) ); dim_obj->UpdateText(); if( context.m_doc.AddObject(dim_obj) ) { context.m_doc.Redraw(); } else { delete dim_obj; } /*INIZIO FUNZIONE CONTROLLO*/ if ( (height - altfondello)>=provapunto.z+10){ ::RhinoApp().Print( L"Funzione controllo altezza OK"); } else{ ::RhinoApp().Print( L"Funzione controllo altezza NOK: CONTROLLARE!! Il valore della testa e' minore del valore minimo di 10 mm. Occorre diminuire l'altezza del fondello o aumentare l'altezza dello stampo."); } /*********************************************/ /* CREATE FONDELLO PLANE */ /*********************************************/ ON_3dPoint point0((63.5 + 20.0),0.0, 0.0); ON_3dPoint point1(-(63.5 + 20.0),0.0, 0.0); ON_LineCurve curve0( point0, point1 ); context.m_doc.AddCurveObject(curve0); context.m_doc.Redraw(); /******************************************************/ /*****************************/ /*USER GIVES NAME TO SURFACES*/ /*****************************/ unsigned int first_sn; unsigned int next_sn; ON_wString obj_name; object_count = context.m_doc.LookupObject( layer, objects ); for(int i = 0; i < object_count; i++ ) { object = objects[ i ]; first_sn = CRhinoObject::NextRuntimeObjectSerialNumber(); /*******************************/ /*TRY CASTING AS A CURVE OBJECT*/ /*******************************/ curve_obj = CRhinoCurveObject::Cast( object ); if( curve_obj ) { const ON_Geometry* geo = curve_obj->Geometry(); const ON_Curve* curve00 = ON_Curve::Cast(geo); ON_3dPoint point = curve00->PointAt(0.0); ON_3dPoint point_ = curve00->PointAt(1.0); if((point.z + point_.z)/2 > 0.0) { obj_name = L"SURFPV"; } else { obj_name = L"SURFFO"; } ON_3dPoint point0(point.x, (point.y + 70.0), point.z); ON_3dPoint point1(point.x, (point.y - 70.0), point.z); ON_LineCurve* curve = new ON_LineCurve(); curve->SetStartPoint(point0); curve->SetEndPoint(point1); ON_SumSurface sumSurf0; sumSurf0.Create(*curve, *curve00); if( context.m_doc.AddSurfaceObject(sumSurf0) ) { context.m_doc.Redraw(); next_sn = CRhinoObject::NextRuntimeObjectSerialNumber(); if( first_sn == next_sn ) { return CRhinoCommand::nothing; } else { SetNametoObject(context.m_doc,first_sn,obj_name,true); } } } }/*CLOSED FOR*/ //int R = 0; //object_count = context.m_doc.LookupObject( layer, objects ); //for(int i = 0; i < object_count; i++) //{ // object = objects[ i ]; // const CRhinoCurveObject* surface_obj = CRhinoCurveObject::Cast(object); // if(surface_obj) // { // R++; // } //} // // Get the string entered by the user // ON_wString obj_name = gs.String(); // obj_name.TrimLeftAndRight(); // // // Is name the same? // if( obj_name.Compare(obj_attribs.m_name) == 0 ) //return CRhinoCommand::nothing; // // // Modify the attributes of the object // obj_attribs.m_name = obj_name; // context.m_doc.ModifyObjectAttributes( objref, obj_attribs ); // if(selectobjectbyuuid_s(context.m_doc,obj_Surf[j],false)) // { //int R = 0; // } ON_wString obj_Surf[2]; ON_wString name; obj_Surf[0] = L"SURFPV"; obj_Surf[1] = L"SURFFO"; object_count = context.m_doc.LookupObject( layer, objects ); int R = 0; /************************/ /*TRY SPLITTING THE BREP*/ /************************/ for(int j = 0; j < 2; j++) { for(int i = 0; i < object_count; i++) { object = objects[ i ]; /*MAKE COPY OF OBJECT ATTRIBUTES. THIS OBJECTS*/ /*HOLDS AN OBJECT'S USER-DEFINED NAME.*/ ON_3dmObjectAttributes obj_attribs = object->Attributes(); name = object->Attributes().m_name; surface_obj = CRhinoSurfaceObject::Cast( object ); if( surface_obj && !surface_obj->IsSolid()) { ON_wString obj_SurfLoc = obj_Surf[j]; /*IS THE CUTTING SURFACE?*/ if( obj_SurfLoc.Compare(name) == 0 ) { R++; } }/*CHIUSURA IF SUPERFICIE*/ } // /************************/ // /*PICK THE BREP TO SPLIT*/ // /************************/ // CRhinoGetObject go; // go.SetCommandPrompt( L"SELECT SOLID TO SPLIT" ); // go.SetGeometryFilter( CRhinoGetObject::polysrf_object );//CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object // go.GetObjects( 1, 1 ); // if( go.CommandResult() != success ) // { //return go.CommandResult(); // } // else // { // RhinoMessageBox(L"CYLINDER IS SELECTED", PlugIn()->PlugInName(), MB_OK | MB_ICONEXCLAMATION ); // } // // const CRhinoObjRef& split_ref = go.Object(0); // // const CRhinoObject* split_object = split_ref.Object(); // if( !split_object ) // { //return failure; // } // // const ON_Brep* split = split_ref.Brep(); // if( !split ) // { //return failure; // } // ON_SimpleArray<ON_Brep*> pieces; // double tol = context.m_doc.AbsoluteTolerance(); // /***********************/ // /*PICK THE CUTTING BREP*/ // /***********************/ // go.SetCommandPrompt( L"SELECT CUTTING SURFACE OR POLYSUFACE" ); // go.SetGeometryFilter( CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object ); // go.EnablePreSelect( FALSE ); // go.EnableDeselectAllBeforePostSelect( FALSE ); // go.GetObjects( 1, 2 ); // if( go.CommandResult() != success ) // { //return go.CommandResult(); // } // const ON_Brep* cutter = go.Object(0).Brep(); // if( !cutter ) // { //return failure; // } // // if( !RhinoBrepSplit(*split, *cutter, tol, pieces) ) // { //RhinoApp().Print( L"UNABLE TO SPLIT BREP.\n" ); // } // // int i, count = pieces.Count(); // if( count == 0 | count == 1 ) // { //if( count == 1 ) //{ // delete pieces[0]; //} //return nothing; // } // // CRhinoObjectAttributes attrib = split_object->Attributes(); // attrib.m_uuid = ON_nil_uuid; // // const CRhinoObjectVisualAnalysisMode* vam_list = split_object->m_analysis_mode_list; // // for( i = 0; i < count; i++ ) // { //CRhinoBrepObject* brep_object = new CRhinoBrepObject( attrib ); //if( brep_object ) //{ // brep_object->SetBrep( pieces[i] ); // if( context.m_doc.AddObject(brep_object) ) // { // RhinoCopyAnalysisModes( vam_list, brep_object ); // } // else // { // delete brep_object; // } //} // } // // context.m_doc.DeleteObject( split_ref ); // context.m_doc.Redraw(); } /*CREATE A NEW LAYER*/ ON_Layer layer; int layer_index = 0; ON_Color color = ON_Color(0, 0, 0); ON_wString layer_name_FONDELLO = L"FONDELLO"; layer.SetLayerName( layer_name_FONDELLO ); layer.SetPlotColor(color.Green()); /*ADD THE LAYER TO THE LAYER TABLE*/ layer_index = context.m_doc.m_layer_table.AddLayer( layer ); ON_wString layer_name_MATRICE = L"MATRICE"; layer.SetLayerName( layer_name_MATRICE ); layer.SetColor(color.Red()); /*ADD THE LAYER TO THE LAYER TABLE*/ layer_index = context.m_doc.m_layer_table.AddLayer( layer ); ON_wString layer_name_FISSO = L"FISSO"; layer.SetLayerName( layer_name_FISSO ); layer.SetColor(color.Blue()); /*ADD THE LAYER TO THE LAYER TABLE*/ layer_index = context.m_doc.m_layer_table.AddLayer( layer ); context.m_doc.Redraw(); /*********************************************************/ } }/*CLOSED IF OVER CHECKING BREP COUNT OBJECT*/ else { RhinoMessageBox(L"THERE IS ALREADY A CYLINDER OBJECT", PlugIn()->PlugInName(), MB_OK | MB_ICONEXCLAMATION ); } } /**********************************************************************/ return CRhinoCommand::success; }
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; }
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; }
extern "C" void rt_revolve_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol) { struct rt_db_internal *tmp_internal; struct rt_revolve_internal *rip; struct rt_sketch_internal *eip; BU_ALLOC(tmp_internal, struct rt_db_internal); RT_DB_INTERNAL_INIT(tmp_internal); rip = (struct rt_revolve_internal *)ip->idb_ptr; RT_REVOLVE_CK_MAGIC(rip); eip = rip->skt; RT_SKETCH_CK_MAGIC(eip); ON_3dPoint plane_origin; ON_3dVector plane_x_dir, plane_y_dir; bool full_revolve = true; if (rip->ang < 2*ON_PI && rip->ang > 0) full_revolve = false; // Find plane in 3 space corresponding to the sketch. vect_t startpoint; VADD2(startpoint, rip->v3d, rip->r); plane_origin = ON_3dPoint(startpoint); plane_x_dir = ON_3dVector(eip->u_vec); plane_y_dir = ON_3dVector(eip->v_vec); const ON_Plane sketch_plane = ON_Plane(plane_origin, plane_x_dir, plane_y_dir); // For the brep, need the list of 3D vertex points. In sketch, they // are stored as 2D coordinates, so use the sketch_plane to define 3 space // points for the vertices. for (size_t i = 0; i < eip->vert_count; i++) { (*b)->NewVertex(sketch_plane.PointAt(eip->verts[i][0], eip->verts[i][1]), 0.0); } // Create the brep elements corresponding to the sketch lines, curves // and bezier segments. Create 2d, 3d and BrepEdge elements for each segment. // Will need to use the bboxes of each element to // build the overall bounding box for the face. Use bGrowBox to expand // a single box. struct line_seg *lsg; struct carc_seg *csg; struct bezier_seg *bsg; uint32_t *lng; for (size_t i = 0; i < (&eip->curve)->count; i++) { lng = (uint32_t *)(&eip->curve)->segment[i]; switch (*lng) { case CURVE_LSEG_MAGIC: { lsg = (struct line_seg *)lng; ON_Curve* lsg3d = new ON_LineCurve((*b)->m_V[lsg->start].Point(), (*b)->m_V[lsg->end].Point()); lsg3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(lsg3d); } break; case CURVE_CARC_MAGIC: csg = (struct carc_seg *)lng; if (csg->radius < 0) { { ON_3dPoint cntrpt = (*b)->m_V[csg->end].Point(); ON_3dPoint edgept = (*b)->m_V[csg->start].Point(); ON_Plane cplane = ON_Plane(cntrpt, plane_x_dir, plane_y_dir); ON_Circle c3dcirc = ON_Circle(cplane, cntrpt.DistanceTo(edgept)); ON_Curve* c3d = new ON_ArcCurve((const ON_Circle)c3dcirc); c3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(c3d); } } else { // need to calculated 3rd point on arc - look to sketch.c around line 581 for // logic } break; case CURVE_BEZIER_MAGIC: bsg = (struct bezier_seg *)lng; { ON_3dPointArray bezpoints = ON_3dPointArray(bsg->degree + 1); for (int j = 0; j < bsg->degree + 1; j++) { bezpoints.Append((*b)->m_V[bsg->ctl_points[j]].Point()); } ON_BezierCurve bez3d = ON_BezierCurve((const ON_3dPointArray)bezpoints); ON_NurbsCurve* beznurb3d = ON_NurbsCurve::New(); bez3d.GetNurbForm(*beznurb3d); beznurb3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(beznurb3d); } break; default: bu_log("Unhandled sketch object\n"); break; } } vect_t endpoint; VADD2(endpoint, rip->v3d, rip->axis3d); const ON_Line& revaxis = ON_Line(ON_3dPoint(rip->v3d), ON_3dPoint(endpoint)); FindLoops(b, &revaxis, rip->ang); // Create the two boundary surfaces, if it's not a full revolution if (!full_revolve) { // First, deduce the transformation matrices to calculate the position of the end surface // The transformation matrices are to rotate an arbitrary point around an arbitrary axis // Let the point A = (x, y, z), the rotation axis is p1p2 = (x2,y2,z2)-(x1,y1,z1) = (a,b,c) // Then T1 is to translate p1 to the origin // Rx is to rotate p1p2 around the X axis to the plane XOZ // Ry is to rotate p1p2 around the Y axis to be coincident to Z axis // Rz is to rotate A with the angle around Z axis (the new p1p2) // RxInv, RyInv, T1Inv are the inverse transformation of Rx, Ry, T1, respectively. // The whole transformation is A' = A*T1*Rx*Ry*Rz*Ry*Inv*Rx*Inv = A*R vect_t end_plane_origin, end_plane_x_dir, end_plane_y_dir; mat_t R; MAT_IDN(R); mat_t T1, Rx, Ry, Rz, RxInv, RyInv, T1Inv; MAT_IDN(T1); VSET(&T1[12], -rip->v3d[0], -rip->v3d[1], -rip->v3d[2]); MAT_IDN(Rx); fastf_t v = sqrt(rip->axis3d[1]*rip->axis3d[1]+rip->axis3d[2]*rip->axis3d[2]); VSET(&Rx[4], 0, rip->axis3d[2]/v, rip->axis3d[1]/v); VSET(&Rx[8], 0, -rip->axis3d[1]/v, rip->axis3d[2]/v); MAT_IDN(Ry); fastf_t u = MAGNITUDE(rip->axis3d); VSET(&Ry[0], v/u, 0, -rip->axis3d[0]/u); VSET(&Ry[8], rip->axis3d[0]/u, 0, v/u); MAT_IDN(Rz); fastf_t C, S; C = cos(rip->ang); S = sin(rip->ang); VSET(&Rz[0], C, S, 0); VSET(&Rz[4], -S, C, 0); bn_mat_inv(RxInv, Rx); bn_mat_inv(RyInv, Ry); bn_mat_inv(T1Inv, T1); mat_t temp; bn_mat_mul4(temp, T1, Rx, Ry, Rz); bn_mat_mul4(R, temp, RyInv, RxInv, T1Inv); VEC3X3MAT(end_plane_origin, plane_origin, R); VADD2(end_plane_origin, end_plane_origin, &R[12]); VEC3X3MAT(end_plane_x_dir, plane_x_dir, R); VEC3X3MAT(end_plane_y_dir, plane_y_dir, R); // Create the start and end surface with rt_sketch_brep() struct rt_sketch_internal sketch; sketch = *(rip->skt); ON_Brep *b1 = ON_Brep::New(); VMOVE(sketch.V, plane_origin); VMOVE(sketch.u_vec, plane_x_dir); VMOVE(sketch.v_vec, plane_y_dir); tmp_internal->idb_ptr = (void *)(&sketch); rt_sketch_brep(&b1, tmp_internal, tol); (*b)->Append(*b1->Duplicate()); ON_Brep *b2 = ON_Brep::New(); VMOVE(sketch.V, end_plane_origin); VMOVE(sketch.u_vec, end_plane_x_dir); VMOVE(sketch.v_vec, end_plane_y_dir); tmp_internal->idb_ptr = (void *)(&sketch); rt_sketch_brep(&b2, tmp_internal, tol); (*b)->Append(*b2->Duplicate()); (*b)->FlipFace((*b)->m_F[(*b)->m_F.Count()-1]); } bu_free(tmp_internal, "free temporary rt_db_internal"); }
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; }
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; }
extern "C" void rt_hyp_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *) { struct rt_hyp_internal *eip; RT_CK_DB_INTERNAL(ip); eip = (struct rt_hyp_internal *)ip->idb_ptr; RT_HYP_CK_MAGIC(eip); point_t p1_origin, p2_origin; ON_3dPoint plane1_origin, plane2_origin; ON_3dVector plane_x_dir, plane_y_dir; // First, find planes corresponding to the top and bottom faces - initially vect_t x_dir, y_dir; VMOVE(x_dir, eip->hyp_A); VCROSS(y_dir, eip->hyp_A, eip->hyp_Hi); VREVERSE(y_dir, y_dir); VMOVE(p1_origin, eip->hyp_Vi); plane1_origin = ON_3dPoint(p1_origin); plane_x_dir = ON_3dVector(x_dir); plane_y_dir = ON_3dVector(y_dir); const ON_Plane hyp_bottom_plane(plane1_origin, plane_x_dir, plane_y_dir); VADD2(p2_origin, eip->hyp_Vi, eip->hyp_Hi); plane2_origin = ON_3dPoint(p2_origin); const ON_Plane hyp_top_plane(plane2_origin, plane_x_dir, plane_y_dir); // Next, create ellipses in the planes corresponding to the edges of the hyp ON_Ellipse b_ell(hyp_bottom_plane, MAGNITUDE(eip->hyp_A), eip->hyp_b); ON_NurbsCurve* bcurve = ON_NurbsCurve::New(); b_ell.GetNurbForm((*bcurve)); bcurve->SetDomain(0.0, 1.0); ON_Ellipse t_ell(hyp_top_plane, MAGNITUDE(eip->hyp_A), eip->hyp_b); ON_NurbsCurve* tcurve = ON_NurbsCurve::New(); t_ell.GetNurbForm((*tcurve)); tcurve->SetDomain(0.0, 1.0); // Generate the bottom cap ON_SimpleArray<ON_Curve*> boundary; boundary.Append(ON_Curve::Cast(bcurve)); ON_PlaneSurface* bp = new ON_PlaneSurface(); bp->m_plane = hyp_bottom_plane; bp->SetDomain(0, -100.0, 100.0); bp->SetDomain(1, -100.0, 100.0); bp->SetExtents(0, bp->Domain(0)); bp->SetExtents(1, bp->Domain(1)); (*b)->m_S.Append(bp); const int bsi = (*b)->m_S.Count() - 1; ON_BrepFace& bface = (*b)->NewFace(bsi); (*b)->NewPlanarFaceLoop(bface.m_face_index, ON_BrepLoop::outer, boundary, true); const ON_BrepLoop* bloop = (*b)->m_L.Last(); bp->SetDomain(0, bloop->m_pbox.m_min.x, bloop->m_pbox.m_max.x); bp->SetDomain(1, bloop->m_pbox.m_min.y, bloop->m_pbox.m_max.y); bp->SetExtents(0, bp->Domain(0)); bp->SetExtents(1, bp->Domain(1)); (*b)->FlipFace(bface); (*b)->SetTrimIsoFlags(bface); boundary.Empty(); delete bcurve; // Generate the top cap boundary.Append(ON_Curve::Cast(tcurve)); ON_PlaneSurface* tp = new ON_PlaneSurface(); tp->m_plane = hyp_top_plane; tp->SetDomain(0, -100.0, 100.0); tp->SetDomain(1, -100.0, 100.0); tp->SetExtents(0, bp->Domain(0)); tp->SetExtents(1, bp->Domain(1)); (*b)->m_S.Append(tp); int tsi = (*b)->m_S.Count() - 1; ON_BrepFace& tface = (*b)->NewFace(tsi); (*b)->NewPlanarFaceLoop(tface.m_face_index, ON_BrepLoop::outer, boundary, true); ON_BrepLoop* tloop = (*b)->m_L.Last(); tp->SetDomain(0, tloop->m_pbox.m_min.x, tloop->m_pbox.m_max.x); tp->SetDomain(1, tloop->m_pbox.m_min.y, tloop->m_pbox.m_max.y); tp->SetExtents(0, bp->Domain(0)); tp->SetExtents(1, bp->Domain(1)); (*b)->SetTrimIsoFlags(tface); delete tcurve; // Now, the hard part. Need an elliptical hyperbolic NURBS surface. // First step is to create a nurbs curve. double MX = eip->hyp_b * eip->hyp_bnr; point_t ep1, ep2, ep3; VSET(ep1, -eip->hyp_b, 0, 0.5*MAGNITUDE(eip->hyp_Hi)); VSET(ep2, -MX*eip->hyp_bnr, 0, 0); VSET(ep3, -eip->hyp_b, 0, -0.5*MAGNITUDE(eip->hyp_Hi)); ON_3dPoint onp1 = ON_3dPoint(ep1); ON_3dPoint onp2 = ON_3dPoint(ep2); ON_3dPoint onp3 = ON_3dPoint(ep3); ON_3dPointArray cpts(3); cpts.Append(onp1); cpts.Append(onp2); cpts.Append(onp3); ON_BezierCurve *bezcurve = new ON_BezierCurve(cpts); bezcurve->MakeRational(); bezcurve->SetWeight(1, bezcurve->Weight(0)/eip->hyp_bnr); ON_NurbsCurve* tnurbscurve = ON_NurbsCurve::New(); bezcurve->GetNurbForm(*tnurbscurve); delete bezcurve; ON_3dPoint revpnt1 = ON_3dPoint(0, 0, -0.5*MAGNITUDE(eip->hyp_Hi)); ON_3dPoint revpnt2 = ON_3dPoint(0, 0, 0.5*MAGNITUDE(eip->hyp_Hi)); ON_Line revaxis = ON_Line(revpnt1, revpnt2); ON_RevSurface* hyp_surf = ON_RevSurface::New(); hyp_surf->m_curve = tnurbscurve; hyp_surf->m_axis = revaxis; hyp_surf->m_angle = ON_Interval(0, 2*ON_PI); // Get the NURBS form of the surface ON_NurbsSurface *hypcurvedsurf = ON_NurbsSurface::New(); hyp_surf->GetNurbForm(*hypcurvedsurf, 0.0); delete hyp_surf; for (int i = 0; i < hypcurvedsurf->CVCount(0); i++) { for (int j = 0; j < hypcurvedsurf->CVCount(1); j++) { point_t cvpt; ON_4dPoint ctrlpt; hypcurvedsurf->GetCV(i, j, ctrlpt); // Scale and shear vect_t proj_ah; vect_t proj_ax; fastf_t factor; VPROJECT(eip->hyp_A, eip->hyp_Hi, proj_ah, proj_ax); VSET(cvpt, ctrlpt.x * MAGNITUDE(proj_ax)/eip->hyp_b, ctrlpt.y, ctrlpt.z); factor = VDOT(eip->hyp_A, eip->hyp_Hi)>0 ? 1.0 : -1.0; cvpt[2] += factor*cvpt[0]/MAGNITUDE(proj_ax)*MAGNITUDE(proj_ah) + 0.5*MAGNITUDE(eip->hyp_Hi)*ctrlpt.w; // Rotate vect_t Au, Bu, Hu; mat_t R; point_t new_cvpt; VSCALE(Bu, y_dir, 1/MAGNITUDE(y_dir)); VSCALE(Hu, eip->hyp_Hi, 1/MAGNITUDE(eip->hyp_Hi)); VCROSS(Au, Bu, Hu); VUNITIZE(Au); MAT_IDN(R); VMOVE(&R[0], Au); VMOVE(&R[4], Bu); VMOVE(&R[8], Hu); VEC3X3MAT(new_cvpt, cvpt, R); VMOVE(cvpt, new_cvpt); // Translate vect_t scale_v; VSCALE(scale_v, eip->hyp_Vi, ctrlpt.w); VADD2(cvpt, cvpt, scale_v); ON_4dPoint newpt = ON_4dPoint(cvpt[0], cvpt[1], cvpt[2], ctrlpt.w); hypcurvedsurf->SetCV(i, j, newpt); } } (*b)->m_S.Append(hypcurvedsurf); int surfindex = (*b)->m_S.Count(); ON_BrepFace& face = (*b)->NewFace(surfindex - 1); (*b)->FlipFace(face); int faceindex = (*b)->m_F.Count(); (*b)->NewOuterLoop(faceindex-1); }
int main(int argc, char *argv[]) { struct db_i *dbip; struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *bot_ip = NULL; struct rt_wdb *wdbp; struct bu_vls name; struct bu_vls bname; struct Mesh_Info *prev_mesh = NULL; struct Mesh_Info *mesh = NULL; bu_vls_init(&name); if (argc != 3) { bu_exit(1, "Usage: %s file.g object", argv[0]); } dbip = db_open(argv[1], DB_OPEN_READWRITE); if (dbip == DBI_NULL) { bu_exit(1, "ERROR: Unable to read from geometry database file %s\n", argv[1]); } if (db_dirbuild(dbip) < 0) bu_exit(1, "ERROR: Unable to read from %s\n", argv[1]); dp = db_lookup(dbip, argv[2], LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_exit(1, "ERROR: Unable to look up object %s\n", argv[2]); } RT_DB_INTERNAL_INIT(&intern) if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) { bu_exit(1, "ERROR: Unable to get internal representation of %s\n", argv[2]); } if (intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { bu_exit(1, "ERROR: object %s does not appear to be of type BoT\n", argv[2]); } else { bot_ip = (struct rt_bot_internal *)intern.idb_ptr; } RT_BOT_CK_MAGIC(bot_ip); for (size_t i_cnt = 1; i_cnt < 3; i_cnt++) { mesh = iterate(bot_ip, prev_mesh); prev_mesh = mesh; // Plot results struct bu_vls fname; bu_vls_init(&fname); bu_vls_printf(&fname, "root3_%d.pl", i_cnt); FILE* plot_file = fopen(bu_vls_addr(&fname), "w"); std::map<size_t, std::vector<size_t> >::iterator f_it; std::vector<size_t>::iterator l_it; int r = int(256*drand48() + 1.0); int g = int(256*drand48() + 1.0); int b = int(256*drand48() + 1.0); for (f_it = mesh->face_pts.begin(); f_it != mesh->face_pts.end(); f_it++) { l_it = (*f_it).second.begin(); plot_face(&mesh->points_p0[(int)(*l_it)], &mesh->points_p0[(int)(*(l_it+1))], &mesh->points_p0[(int)(*(l_it+2))], r, g , b, plot_file); } fclose(plot_file); } // When constructing the final BoT, use the limit points for all // vertices ON_3dPointArray points_inf; for (size_t v = 0; v < (size_t)mesh->points_p0.Count(); v++) { points_inf.Append(*mesh->points_p0.At((int)v)); //point_inf(v, mesh, &points_inf); } // The subdivision process shrinks the bot relative to its original // vertex positions - to better approximate the original surface, // average the change in position of the original vertices to get a // scaling factor and apply it to all points in the final mesh. fastf_t scale = 0.0; for (size_t pcnt = 0; pcnt < bot_ip->num_vertices; pcnt++) { ON_3dVector v1(ON_3dPoint(&bot_ip->vertices[pcnt*3])); ON_3dVector v2(*points_inf.At((int)pcnt)); scale += 1 + (v1.Length() - v2.Length())/v1.Length(); } scale = scale / bot_ip->num_vertices; for (size_t pcnt = 0; pcnt < (size_t)points_inf.Count(); pcnt++) { ON_3dPoint p0(*points_inf.At((int)pcnt)); ON_3dPoint p1 = p0 * scale; *points_inf.At((int)pcnt) = p1; } wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK); fastf_t *vertices = (fastf_t *)bu_malloc(sizeof(fastf_t) * points_inf.Count() * 3, "new verts"); int *faces = (int *)bu_malloc(sizeof(int) * mesh->face_pts.size() * 3, "new faces"); for (size_t v = 0; v < (size_t)points_inf.Count(); v++) { vertices[v*3] = points_inf[(int)v].x; vertices[v*3+1] = points_inf[(int)v].y; vertices[v*3+2] = points_inf[(int)v].z; } std::map<size_t, std::vector<size_t> >::iterator f_it; std::vector<size_t>::iterator l_it; for (f_it = mesh->face_pts.begin(); f_it != mesh->face_pts.end(); f_it++) { l_it = (*f_it).second.begin(); faces[(*f_it).first*3] = (*l_it); faces[(*f_it).first*3+1] = (*(l_it + 1)); faces[(*f_it).first*3+2] = (*(l_it + 2)); } bu_vls_init(&bname); bu_vls_sprintf(&bname, "%s_subd", argv[2]); mk_bot(wdbp, bu_vls_addr(&bname), RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, points_inf.Count(), mesh->face_pts.size(), vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); wdb_close(wdbp); bu_vls_free(&bname); bu_free(vertices, "free subdivision BoT vertices"); bu_free(faces, "free subdivision BoT faces"); return 0; }
extern "C" void rt_eto_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *) { struct rt_eto_internal *eip; RT_CK_DB_INTERNAL(ip); eip = (struct rt_eto_internal *)ip->idb_ptr; RT_ETO_CK_MAGIC(eip); point_t p_origin; vect_t v1, v1a, x_dir, y_dir; ON_3dPoint plane_origin; ON_3dVector plane_x_dir, plane_y_dir; double ell_axis_len_1, ell_axis_len_2; // First, find a plane in 3 space with x and y axes // along an axis of the ellipse to be rotated, and its // coordinate origin at the center of the ellipse. // // To identify a point on the eto suitable for use (there // are of course infinitely many such points described by // a circle at radius eto_r from the eto vertex) obtain // a vector at a right angle to the eto normal, unitize it // and scale it. VCROSS(v1, eip->eto_C, eip->eto_N); if (NEAR_ZERO(MAGNITUDE(v1), VUNITIZE_TOL)) { vect_t dir_vect; VSET(dir_vect, 0, 1, 0); VCROSS(v1, dir_vect, eip->eto_N); if (NEAR_ZERO(MAGNITUDE(v1), VUNITIZE_TOL)) { VSET(dir_vect, 1, 0, 0); VCROSS(v1, dir_vect, eip->eto_N); } } point_t temp; VMOVE(temp, v1); VCROSS(v1a, v1, eip->eto_N); VSET(v1, -v1a[0], -v1a[1], -v1a[2]); VUNITIZE( v1 ); VSCALE(v1, v1, eip->eto_r); VADD2(v1, v1, eip->eto_V); VMOVE(x_dir, eip->eto_C); VCROSS(y_dir, x_dir, temp); VSET(p_origin, v1[0], v1[1], v1[2]); plane_origin = ON_3dPoint(p_origin); plane_x_dir = ON_3dVector(x_dir); plane_y_dir = ON_3dVector(y_dir); const ON_Plane ell_plane(plane_origin, plane_x_dir, plane_y_dir); // Once the plane has been created, create the ellipse // within the plane. ell_axis_len_1 = MAGNITUDE(eip->eto_C); ell_axis_len_2 = eip->eto_rd; ON_Ellipse ellipse(ell_plane, ell_axis_len_1, ell_axis_len_2); // Generate an ON_Curve from the ellipse and revolve it // around eto_N ON_NurbsCurve ellcurve; ellipse.GetNurbForm(ellcurve); point_t eto_endvertex; VADD2(eto_endvertex, eip->eto_V, eip->eto_N); ON_3dPoint eto_vertex_pt = ON_3dPoint(eip->eto_V); ON_3dPoint eto_endvertex_pt = ON_3dPoint(eto_endvertex); ON_Line revaxis = ON_Line(eto_vertex_pt, eto_endvertex_pt); ON_RevSurface* eto_surf = ON_RevSurface::New(); eto_surf->m_curve = &ellcurve; eto_surf->m_axis = revaxis; /* Create brep with one face*/ ON_BrepFace *newface = (*b)->NewFace(*eto_surf); (*b)->FlipFace(*newface); // (*b)->Standardize(); // (*b)->Compact(); }
extern "C" void rt_ehy_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *) { struct rt_ehy_internal *eip; RT_CK_DB_INTERNAL(ip); eip = (struct rt_ehy_internal *)ip->idb_ptr; RT_EHY_CK_MAGIC(eip); // Check the parameters if (!NEAR_ZERO(VDOT(eip->ehy_Au, eip->ehy_H), RT_DOT_TOL)) { bu_log("rt_ehy_brep: Au and H are not perpendicular!\n"); return; } if (!NEAR_EQUAL(MAGNITUDE(eip->ehy_Au), 1.0, RT_LEN_TOL)) { bu_log("rt_ehy_brep: Au not a unit vector!\n"); return; } if (MAGNITUDE(eip->ehy_H) < RT_LEN_TOL || eip->ehy_c < RT_LEN_TOL || eip->ehy_r1 < RT_LEN_TOL || eip->ehy_r2 < RT_LEN_TOL) { bu_log("rt_ehy_brep: not all dimensions positive!\n"); return; } if (eip->ehy_r2 > eip->ehy_r1) { bu_log("rt_ehy_brep: semi-minor axis cannot be longer than semi-major axis!\n"); return; } point_t p1_origin; ON_3dPoint plane1_origin, plane2_origin; ON_3dVector plane_x_dir, plane_y_dir; // First, find plane in 3 space corresponding to the bottom face of the EPA. vect_t x_dir, y_dir; VMOVE(x_dir, eip->ehy_Au); VCROSS(y_dir, eip->ehy_Au, eip->ehy_H); VUNITIZE(y_dir); VMOVE(p1_origin, eip->ehy_V); plane1_origin = ON_3dPoint(p1_origin); plane_x_dir = ON_3dVector(x_dir); plane_y_dir = ON_3dVector(y_dir); const ON_Plane ehy_bottom_plane(plane1_origin, plane_x_dir, plane_y_dir); // Next, create an ellipse in the plane corresponding to the edge of the ehy. ON_Ellipse ellipse1(ehy_bottom_plane, eip->ehy_r1, eip->ehy_r2); ON_NurbsCurve* ellcurve1 = ON_NurbsCurve::New(); ellipse1.GetNurbForm((*ellcurve1)); ellcurve1->SetDomain(0.0, 1.0); // Generate the bottom cap ON_SimpleArray<ON_Curve*> boundary; boundary.Append(ON_Curve::Cast(ellcurve1)); ON_PlaneSurface* bp = new ON_PlaneSurface(); bp->m_plane = ehy_bottom_plane; bp->SetDomain(0, -100.0, 100.0); bp->SetDomain(1, -100.0, 100.0); bp->SetExtents(0, bp->Domain(0)); bp->SetExtents(1, bp->Domain(1)); (*b)->m_S.Append(bp); const int bsi = (*b)->m_S.Count() - 1; ON_BrepFace& bface = (*b)->NewFace(bsi); (*b)->NewPlanarFaceLoop(bface.m_face_index, ON_BrepLoop::outer, boundary, true); const ON_BrepLoop* bloop = (*b)->m_L.Last(); bp->SetDomain(0, bloop->m_pbox.m_min.x, bloop->m_pbox.m_max.x); bp->SetDomain(1, bloop->m_pbox.m_min.y, bloop->m_pbox.m_max.y); bp->SetExtents(0, bp->Domain(0)); bp->SetExtents(1, bp->Domain(1)); (*b)->SetTrimIsoFlags(bface); delete ellcurve1; // Now, the hard part. Need an elliptical hyperbolic NURBS surface // First step is to create a nurbs curve. double intercept_calc = (eip->ehy_c)*(eip->ehy_c)/(MAGNITUDE(eip->ehy_H) + eip->ehy_c); double intercept_dist = MAGNITUDE(eip->ehy_H) + eip->ehy_c - intercept_calc; double intercept_length = intercept_dist - MAGNITUDE(eip->ehy_H); double MX = MAGNITUDE(eip->ehy_H); double MP = MX + intercept_length; double w = (MX/MP)/(1-MX/MP); point_t ep1, ep2, ep3; VSET(ep1, -eip->ehy_r1, 0, 0); VSET(ep2, 0, 0, w*intercept_dist); VSET(ep3, eip->ehy_r1, 0, 0); ON_3dPoint onp1 = ON_3dPoint(ep1); ON_3dPoint onp2 = ON_3dPoint(ep2); ON_3dPoint onp3 = ON_3dPoint(ep3); ON_3dPointArray cpts(3); cpts.Append(onp1); cpts.Append(onp2); cpts.Append(onp3); ON_BezierCurve *bcurve = new ON_BezierCurve(cpts); bcurve->MakeRational(); bcurve->SetWeight(1, w); ON_NurbsCurve* tnurbscurve = ON_NurbsCurve::New(); bcurve->GetNurbForm(*tnurbscurve); ON_NurbsCurve* hypbnurbscurve = ON_NurbsCurve::New(); const ON_Interval subinterval = ON_Interval(0, 0.5); tnurbscurve->GetNurbForm(*hypbnurbscurve, 0.0, &subinterval); // Next, rotate that curve around the height vector. point_t revpoint1, revpoint2; VSET(revpoint1, 0, 0, 0); VSET(revpoint2, 0, 0, MX); ON_3dPoint rpnt1 = ON_3dPoint(revpoint1); ON_3dPoint rpnt2 = ON_3dPoint(revpoint2); ON_Line revaxis = ON_Line(rpnt1, rpnt2); ON_RevSurface* hyp_surf = ON_RevSurface::New(); hyp_surf->m_curve = hypbnurbscurve; hyp_surf->m_axis = revaxis; hyp_surf->m_angle = ON_Interval(0, 2*ON_PI); // Get the NURBS form of the surface ON_NurbsSurface *ehycurvedsurf = ON_NurbsSurface::New(); hyp_surf->GetNurbForm(*ehycurvedsurf, 0.0); delete hyp_surf; delete tnurbscurve; delete bcurve; // Transformations for (int i = 0; i < ehycurvedsurf->CVCount(0); i++) { for (int j = 0; j < ehycurvedsurf->CVCount(1); j++) { point_t cvpt; ON_4dPoint ctrlpt; ehycurvedsurf->GetCV(i, j, ctrlpt); // Scale the control points of the // resulting surface to map to the shorter axis. VSET(cvpt, ctrlpt.x, ctrlpt.y * eip->ehy_r2/eip->ehy_r1, ctrlpt.z); // Rotate according to the directions of Au and H vect_t Hu; mat_t R; point_t new_cvpt; VSCALE(Hu, eip->ehy_H, 1/MAGNITUDE(eip->ehy_H)); MAT_IDN(R); VMOVE(&R[0], eip->ehy_Au); VMOVE(&R[4], y_dir); VMOVE(&R[8], Hu); VEC3X3MAT(new_cvpt, cvpt, R); VMOVE(cvpt, new_cvpt); // Translate according to V vect_t scale_v; VSCALE(scale_v, eip->ehy_V, ctrlpt.w); VADD2(cvpt, cvpt, scale_v); ON_4dPoint newpt = ON_4dPoint(cvpt[0], cvpt[1], cvpt[2], ctrlpt.w); ehycurvedsurf->SetCV(i, j, newpt); } } (*b)->m_S.Append(ehycurvedsurf); int surfindex = (*b)->m_S.Count(); ON_BrepFace& face = (*b)->NewFace(surfindex - 1); (*b)->FlipFace(face); int faceindex = (*b)->m_F.Count(); (*b)->NewOuterLoop(faceindex-1); }
void RSpline::updateFromControlPoints() const { #ifndef R_NO_OPENNURBS if (controlPoints.size()<degree+1) { invalidate(); qWarning() << "RSpline::updateFromControlPoints: not enough control points: " << controlPoints.size(); return; } // periodic: if (periodic && !hasFitPoints()) { ON_3dPoint* points = new ON_3dPoint[controlPoints.size()]; for (int i=0; i<controlPoints.size(); ++i) { RVector cp = controlPoints.at(i); points[i] = ON_3dPoint(cp.x, cp.y, cp.z); } curve.CreatePeriodicUniformNurbs(3, getOrder(), controlPoints.size(), points); delete[] points; } // open or from fit points: else { curve.Create(3, false, getOrder(), controlPoints.size()); // setting control points: for (int i=0; i<controlPoints.size(); ++i) { RVector cp = controlPoints.at(i); ON_3dPoint onp(cp.x, cp.y, cp.z); curve.SetCV(i, onp); //qDebug() << "RSpline: controlPoints[" << i << "]: " << cp; } bool knotCondition = (knotVector.size() == getOrder() + controlPoints.size() - 2); //knotCondition = true; // genetate knot vector automatically: if (knotVector.isEmpty() || !knotCondition) { // if (!knotVector.isEmpty()) { // qDebug() << "RSpline: knotVector ignored"; // qDebug() << "RSpline: knots: " << knotVector.size(); // qDebug() << "RSpline: order: " << getOrder(); // qDebug() << "RSpline: controlPoints: " << controlPoints.size(); // } int si = ON_KnotCount(getOrder(), controlPoints.size()); double* knot = new double[si]; //ON_MakePeriodicUniformKnotVector(getOrder(), controlPoints.size(), knot); ON_MakeClampedUniformKnotVector(getOrder(), controlPoints.size(), knot); for (int i=0; i<si; ++i) { // qDebug() << "RSpline: knot[" << i << "]: " << knot[i]; curve.SetKnot(i, knot[i]); } delete[] knot; } else { int k=0; for (int i=0; i<knotVector.count(); ++i) { //qDebug() << "RSpline: knot[" << i << "]: " << knotVector.at(i); bool ok = curve.SetKnot(k++, knotVector.at(i)); if (!ok) { //qDebug() << "RSpline: knot[" << i << "]: NOT set"; } } } } //##getExploded(); #endif }
CRhinoCommand::result CCommandVRCreateViews::RunCommand( const CRhinoCommandContext& context ) { AFX_MANAGE_STATE( ::RhinoApp().RhinoModuleState() ); // dunno, from example ON_wString wStr; wStr.Format( L"READY SET\n", EnglishCommandName() ); RhinoApp().Print( wStr ); ON_SimpleArray<CRhinoView*> viewList; // don't know what is up with* this* ON_SimpleArray<ON_UUID> viewportIds; CRhinoView* lView = 0; CRhinoView* rView = 0; ON_SimpleArray<CRhinoView*> lrViews; // will contain our vr views int i = 0; // also use this in loops int lr = 0; // use to track 1st and 2nd find // builds a list of (current) viewport IDs context.m_doc.GetViewList( viewList, true, false ); for ( i = 0; i < viewList.Count(); i ++) { CRhinoView* tempView = viewList[i]; // pull view out -> this is redeclared here, in sample, but not in second loop if (tempView) viewportIds.Append( tempView->ActiveViewportID() ); } viewList.Empty(); // empty bc we are going to re-build later when new views context.m_doc.NewView( ON_3dmView() ); context.m_doc.NewView( ON_3dmView() ); // we will build two // find viewport UUID just created context.m_doc.GetViewList( viewList, true, false); for (i = 0; i < viewList.Count(); i++) { CRhinoView* tempView = viewList[i]; if (tempView) { int rc = viewportIds.Search( tempView->ActiveViewportID() ); // returns index of 1st element which satisfies search. returns -1 when no such item found if (rc < 0 ) // if current tempView did not exist prior to this running { if (lr > 0) // and if lr already found 1 { rView = tempView; // right is 2nd view we find break; // so this breaks when we find, and lView is left as the viewList[i] where we found the new viewport, whose ID was not in our list. // and we are left with lView being = viewList[i] at new view } if (lr == 0) { lView = tempView; // left is 1st view lr = 1; } } else tempView = 0; // reset lView to null and re-loop } } lrViews.Append(lView); lrViews.Append(rView); // init points ON_3dPoint locationL = ON_3dPoint(100.0,100.0,100.0); ON_3dPoint locationR = ON_3dPoint(100.0,165.1,100.0); ON_3dPoint targetSetup = ON_3dPoint(0,0,0); if (lView && rView) { for (int i = 0; i < 2; i++) { // RhinoApp().ActiveView()-> ON_3dmView onView = lrViews[i]->ActiveViewport().View(); if(i == 0) onView.m_name = L"lView"; //lrViews[i]->MoveWindow(0,0,VR().resolution.w/2,VR().resolution.h, true); if(i == 1) onView.m_name = L"rView"; //lrViews[i]->MoveWindow(960,0,VR().resolution.w/2,VR().resolution.h, true); lrViews[i]->ActiveViewport().SetView(onView); lrViews[i]->ActiveViewport().m_v.m_vp.ChangeToPerspectiveProjection(50,true,35); lrViews[i]->ActiveViewport().m_v.m_vp.SetCameraLocation(locationL); lrViews[i]->FloatRhinoView(true); lrViews[i]->Redraw(); } } VR().lView = lView; VR().rView = rView; ON_wString SYNC; SYNC.Format(L"SYNCVRBEGIN\n" ); RhinoApp().Print( SYNC ); if (vrConduit.IsEnabled() && ::IsWindow( vrConduit.m_hWnd1 ) && ::IsWindow( vrConduit.m_hWnd2 ) ) // if is already enabled ? { vrConduit.m_pView1 = 0; vrConduit.m_pView2 = 0; vrConduit.Disable(); } else { vrConduit.m_pView1 = lView; vrConduit.m_pView2 = rView; vrConduit.m_hWnd1 = vrConduit.m_pView1->m_hWnd; vrConduit.m_hWnd2 = vrConduit.m_pView2->m_hWnd; SyncVR(lView, rView); // ok it runs once. we should also set them up perspective & looking at 0,0 vrConduit.Bind( *lView ); vrConduit.Bind( *rView ); lView->Redraw(); rView->Redraw(); vrConduit.Enable(); } // but do not update names immediately; have to refresh somehow // now re-name update positions outside of loop: continuously // bring in OVR Tracking and assign to VR Viewports // then, orbit? return CRhinoCommand::success; }