bool ON_LineCurve::Extend( const ON_Interval& domain ) { double len = Domain().Length(); ON_3dVector V = m_line.Direction(); ON_3dPoint Q0 = m_line.from; ON_3dPoint Q1 = m_line.to; double t0 = Domain()[0]; double t1 = Domain()[1]; bool do_it = false; if (domain[1] > Domain()[1]) { Q1 += (domain[1]-Domain()[1])/len*V; t1 = domain[1]; do_it = true; } if (domain[0] < Domain()[0]) { Q0 += (domain[0]-Domain()[0])/len*V; t0 = domain[0]; do_it = true; } if (do_it){ m_line = ON_Line(Q0, Q1); SetDomain(t0, t1); DestroyCurveTree(); } return do_it; }
int TriIntersections::Faces( ON_ClassArray<ON_3dPoint[3]> UNUSED(faces) ) { if (intersections.Count() == 0) { return 0; } /* first we get an array of all the segments we can use to make * our faces. */ ON_SimpleArray<ON_Line> segments; /*the segments we have to make faces */ ON_SimpleArray<bool> flippable; /* whether or not the segment has direction */ ON_SimpleArray<bool> segexternal; /* whether or not the segment is from the edge */ for (int i = 0; i < intersections.Count(); i++) { segments.Append(intersections[i]); segments.Append(intersections[i]); flippable.Append(false); flippable.Append(false); segexternal.Append(false); segexternal.Append(false); } for (int i = 0; i < 3; i++) { if (edges[i].Count() == 2) { /* the edge was never intersected */ segments.Append(ON_Line(edges[i][0], edges[i][0])); flippable.Append(true); segexternal.Append(true); } else { for (int j = 0; j < (edges[i].Count() - 1); j++) { if (dir[i][j] == dir[i][j + 1]) { /* this indicates an error in the intersection data */ return -1; } else if (dir[i][j] == 0 || dir[i][j+1] == 1) { segments.Append(ON_Line(edges[i][j], edges[i][j+1])); flippable.Append(false); segexternal.Append(true); } else { segments.Append(ON_Line(edges[i][j+1], edges[i][j])); flippable.Append(false); segexternal.Append(true); } } } } /* Now that the segments are all set up it's time to make them * into faces. */ ON_ClassArray<ON_Polyline> outlines; ON_SimpleArray<bool> line_external; /* stores whether each polyline is internal */ ON_Polyline outline; while (segments.Count() != 0) { outline.Append(segments[0].from); outline.Append(segments[0].to); segments.Remove(0); int i = 0; bool ext = false; /* keeps track of the ternality of the path we're assembling */ while (!outline.IsClosed(tol)) { if (i >= segments.Count()) { return -1; } else if (VNEAR_EQUAL(segments[i].from, outline[outline.Count() - 1], tol)) { outline.Append(segments[i].to); } else if (VNEAR_EQUAL(segments[i].to, outline[0], tol)) { outline.Insert(0, segments[i].from); } else if (VNEAR_EQUAL(segments[i].from, outline[0], tol) && flippable[i]) { outline.Insert(0, segments[i].to); } else if (VNEAR_EQUAL(segments[i].to, outline[outline.Count() - 1], tol) && flippable[i]) { outline.Append(segments[i].from); } else { i++; continue; } /* only executed when we append edge i */ segments.Remove(i); flippable.Remove(i); ext &= segexternal[i]; segexternal.Remove(i); i = 0; } outlines.Append(outline); line_external.Append(ext); } /* XXX - now we need to setup the ternality tree for the paths */ return 0; }
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); }
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); }
ON_Line ON_Cone::LineAt( double radial_parameter ) const { return ON_Line(PointAt(radial_parameter,height),ApexPoint()); }
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"); }
CRhinoCommand::result CGenUgello::RunCommand( const CRhinoCommandContext& context ) { Cscript1PlugIn& plugin = script1PlugIn(); if( !plugin.IsDlgVisible() ) { return CRhinoCommand::nothing; } /*GET A REFERENCE TO THE LAYER TABLE*/ CRhinoLayerTable& layer_table = context.m_doc.m_layer_table; CRhinoGetObject go9; go9.SetCommandPrompt( L"Select object to change name" ); go9.EnablePreSelect( TRUE ); go9.EnableSubObjectSelect( FALSE ); go9.GetObjects( 1, 1 ); if( go9.CommandResult() != CRhinoCommand::success ) return go9.CommandResult(); // Get the object reference const CRhinoObjRef& objref9 = go9.Object(0); // Get the object const CRhinoObject* obj9 = objref9.Object(); obj9->Select( false ); if( !obj9 ) return CRhinoCommand::failure; // Make copy of object attributes. This objects // holds an object's user-defined name. ON_3dmObjectAttributes obj_attribs9 = obj9->Attributes(); //Prompt for new object name CRhinoGetString gs1; //gs1.SetDefaultString( /*gs1.SetCommandPrompt( L"New object name" ); gs1.SetDefaultString( obj_attribs9.m_name ); gs1.AcceptNothing( TRUE ); gs1.GetString(); if( gs1.CommandResult() != CRhinoCommand::success ) return gs1.CommandResult();*/ // Get the string entered by the user // ON_wString obj_name1 = gs1.String(); // //obj_name.TrimLeftAndRight(); ////const wchar_t* prova5 = new(L"testo"); // //wchar_t name( L"testo" ); //const wchar_t* szName = gs1.String(); CTestUserData* ud = CTestUserData::Cast( obj_attribs9.GetUserData(ud->Id()) ); ON_wString obj_name = L"ugello22"; selectobjectbyuuid_s(context.m_doc,obj_name,true); //SelectObjectByUuid(context.m_doc,obj_attribs9.m_uuid,true); //begin calcolo il punto di intersezione per disegnare l'ugello double valore_ugello =(_wtof(plugin.m_dialog->ValIniezioneDisassamento)); ON_3dPoint inizio_linea (valore_ugello,0,0); ON_3dPoint fine_linea (valore_ugello,0,130); ON_Line line_ugello( inizio_linea, fine_linea ); const ON_LineCurve* crv3 = new ON_LineCurve(line_ugello); //crv3->DuplicateCurve // context.m_doc.AddCurveObject( line_ugello ); //begin deseleziona tutto const CRhinoLayer& layer = context.m_doc.m_layer_table.CurrentLayer(); ON_SimpleArray<CRhinoObject*> obj_list; int j, obj_count = context.m_doc.LookupObject( layer, obj_list ); for( j = 0; j < obj_count; j++ ) { CRhinoObject* obj = obj_list[j]; if( obj && obj->IsSelectable() ) obj->UnselectAllSubObjects(); //obj->Select(false); if( obj_count ) context.m_doc.Redraw(); } // end deseleziona tutto //const ON_Object* obj_ptr = context.m_doc.LookupDocumentObject(pvcurva, false); // CRhinoObjRef& objref5 = CRhinoObject* LookupObject(pvcurva); //SelectObjectByUuid( context.m_doc, pvcurva, true ); //const CRhinoObject* object = context.m_doc.LookupObject( pvcurva ); //ON_TextLog* text_log; //object->IsValid(); // inizio esempio // Select two curves to intersect CRhinoGetObject go; go.SetCommandPrompt( L"Seleziona la linea originale del Piano Visionale" ); go.SetGeometryFilter( ON::curve_object ); go.GetObjects( 1, 1 ); if( go.CommandResult() != CRhinoCommand::success ) return go.CommandResult(); // Validate input const ON_Curve* curveA = go.Object(0).Curve(); const ON_Curve* curveB = crv3;//go.Object(1).Curve(); if( 0 == curveA | 0 == curveB ) return CRhinoCommand::failure; // Calculate the intersection double intersection_tolerance = 0.001; double overlap_tolerance = 0.0; ON_SimpleArray<ON_X_EVENT> events; int count = curveA->IntersectCurve( curveB, events, intersection_tolerance, overlap_tolerance ); ON_3dPoint PuntoIntersezione; // Process the results if( count > 0 ) { ::RhinoApp().Print( L"Intersezione punto per ugello trovato"); int i; for( i = 0; i < events.Count(); i++ ) { const ON_X_EVENT& e = events[i]; context.m_doc.AddPointObject( e.m_A[0] ); if( e.m_A[0].DistanceTo(e.m_B[0]) > ON_EPSILON ) { context.m_doc.AddPointObject( e.m_B[0] ); context.m_doc.AddCurveObject( ON_Line(e.m_A[0], e.m_B[0]) ); PuntoIntersezione = e.m_B[0]; } } context.m_doc.Redraw(); } /* ON_UUID uuid = obj->Attributes().m_uuid; ON_wString str; ON_UuidToString( uuid, str ); ::RhinoApp().Print( L"The object's unique identifier is \"%s\".\n", str );*/ // fine esempio //const CRhinoObjRef& objref1 = ref; //era object /*const ON_LineCurve* GetLineCurve( const ON_Curve* pC5 ){ const ON_LineCurve* p = 0; if( pC5 != 0 ) p = ON_LineCurve::Cast( pC5 ); return p; // }*/ // // const ON_LineCurve* pC5 = ON_LineCurve::Cast( ref.Geometry() ); //// // ON_Line line1 = crv7->m_line; //// //ON_Line line1 = pC5-> // ON_3dVector v0 = line_ugello.to - line_ugello.from; //v0.Unitize(); //ON_3dVector v1 = line1.to - line1.from; //v1.Unitize(); //if( v0.IsParallelTo(v1) != 0 ) //{ // RhinoApp().Print( L"Selected lines are parallel.\n" ); // return nothing; //} // ON_Line ray0( line_ugello.from, line_ugello.from + v0 ); //ON_Line ray1( line1.from, line1.from + v1 ); //double s = 0, t = 0; //if( !ON_Intersect(ray0, ray1, &s, &t) ) //{ // RhinoApp().Print( L"No intersection found.\n" ); // return nothing; //} //ON_3dPoint pt0 = line_ugello.from + s * v0; //ON_3dPoint pt1 = line1.from + t * v1; //context.m_doc.AddPointObject( pt0 ); // //context.m_doc.Redraw(); //go5.g // const CRhinoObjRef& objref5 = go5.; //CRhinoGetObject; //CRhinoDoc::LookupDocumentObject( //begin calcolo il punto di intersezione per disegnare l'ugello ON_3dPoint bottom_pt = PuntoIntersezione; // l'altro punto, e.m_A[0], non e' preciso. double bottom_radius = 3.25; ON_Circle bottom_circle( bottom_pt, bottom_radius ); ON_3dPoint top_pt = PuntoIntersezione; top_pt.z+=8.0; double top_radius = 11; ON_Circle top_circle( top_pt, top_radius ); ON_RevSurface* revsrf = new ON_RevSurface; ON_LineCurve* pShapeCurve = new ON_LineCurve; revsrf->m_curve = pShapeCurve; pShapeCurve->m_dim = 3; pShapeCurve->m_line.from = bottom_circle.PointAt(0); pShapeCurve->m_line.to = top_circle.PointAt(0); pShapeCurve->m_t.Set(0, pShapeCurve->m_line.from.DistanceTo(pShapeCurve->m_line.to)); revsrf->m_axis.from = bottom_circle.Center(); revsrf->m_axis.to = top_circle.Center(); revsrf->m_angle[0] = revsrf->m_t[0] = 0.0; revsrf->m_angle[1] = revsrf->m_t[1] = 2.0*ON_PI; ON_Brep* tcone_brep = ON_BrepRevSurface(revsrf, TRUE, TRUE ); unsigned int first_sn = CRhinoObject::NextRuntimeObjectSerialNumber(); if( tcone_brep ) { CRhinoBrepObject* tcone_object = new CRhinoBrepObject(); tcone_object->SetBrep( tcone_brep ); if( context.m_doc.AddObject(tcone_object) ) context.m_doc.Redraw(); else delete tcone_object; } unsigned int next_sn = CRhinoObject::NextRuntimeObjectSerialNumber(); /*IF THE TWO ARE THE SAME, THEN NOTHING HAPPENED*/ if( first_sn == next_sn ) return CRhinoCommand::nothing; else { ON_wString obj_name = L"ugello"; SetNametoObject(context.m_doc,first_sn,obj_name,true); } ////// // CRhinoGetObject go; //go.SetCommandPrompt( L"Select edge of surface to extend" ); //go.SetGeometryFilter(CRhinoGetObject::edge_object); //go.SetGeometryAttributeFilter( CRhinoGetObject::edge_curve ); //go.GetObjects( 1, 1 ); //if( go.CommandResult() != CRhinoCommand::success ) // return go.CommandResult(); //const CRhinoObjRef& objref = go.Object(0); //const ON_Surface* srf = objref.Surface(); //if( !srf ) //{ // RhinoApp().Print( L"Unable to extend polysurfaces.\n" ); // return CRhinoCommand::nothing; //} //const ON_Brep* brep = objref.Brep(); //const ON_BrepFace* face = objref.Face(); //if( !brep | !face | face->m_face_index < 0 ) // return CRhinoCommand::failure; //if( !brep->IsSurface() ) //{ // RhinoApp().Print( L"Unable to extend trimmed surfaces.\n" ); // return CRhinoCommand::nothing; //} //const ON_BrepTrim* trim = objref.Trim(); //if( !trim ) // return CRhinoCommand::failure; //ON_Surface::ISO edge_index( trim->m_iso ); //int dir = edge_index % 2; //if( srf->IsClosed(1-dir) ) //{ // RhinoApp().Print(L"Unable to extend surface at seam.\n" ); // return CRhinoCommand::nothing; //} //if( edge_index < ON_Surface::W_iso | edge_index > ON_Surface::N_iso ) //{ // RhinoApp().Print( L"Selected edge must be an underlying surface edge.\n" ); // return CRhinoCommand::nothing; //} //ON_Surface* myface = srf->DuplicateSurface(); //if( !myface ) // return CRhinoCommand::failure; //bool rc = RhinoExtendSurface( myface, edge_index, 5.0, true); //if( rc ) //{ // ON_Brep* mybrep = new ON_Brep(); // mybrep->Create( myface ); // CRhinoBrepObject* obj = new CRhinoBrepObject(); // obj->SetBrep( mybrep ); // context.m_doc.ReplaceObject( CRhinoObjRef(objref.Object()), obj ); // context.m_doc.Redraw(); //} ///////// return CRhinoCommand::success; }