RH_C_FUNCTION ON_BezierCurve* ON_BezierCurve_New3d(int count, /*ARRAY*/const ON_3dPoint* points) { ON_BezierCurve* rc = NULL; if( count && points ) { ON_3dPointArray pts; pts.Append(count, points); rc = new ON_BezierCurve(pts); pts.KeepArray(); } return rc; }
void Spline::populateCurve() { // std::cout << "Populating"; // convert LC Spline Control points to nurbs type coordinates. ON_3dPointArray points; for(const auto& p: _controlPoints) { points.Append(ON_3dPoint(p.x(), p.y(), p.z())); } auto cpcount = _controlPoints.size(); // UNIFORM OPEN CURVE if(_flags == splineflag::PERIODIC) { _splineCurve.CreatePeriodicUniformNurbs(3, _degree+1, cpcount, points); } // UNIFORM BUT CLOSED ONE else if (_knotPoints.size()==0) { _splineCurve.Create(3, false, _degree+1, cpcount); auto i = 0; for(auto i = 0; i < cpcount; i++) { _splineCurve.SetCV(i, points[i]); } int knotcount = _degree+cpcount-1; double* knots = new double[knotcount]; ON_MakeClampedUniformKnotVector(_degree+1, cpcount, knots); for (int i=0; i<knotcount; ++i) { _splineCurve.SetKnot(i, knots[i]); } delete knots; } // NON UNIFORM NURBS. else if(knotPoints().size() > 0) { _splineCurve.Create(3, false, _degree+1, cpcount); // SET CP's for(auto i = 0; i < cpcount; i++) { _splineCurve.SetCV(i, points[i]); } // SET Knot vectors auto i = 0; for(const auto& kp: _knotPoints) { _splineCurve.SetKnot(i, kp); i++; } } }
void CGetPolylinePoints::DynamicDraw( HDC hdc, CRhinoViewport& vp, const ON_3dPoint& pt ) { if( m_point_array.Count() > 0 ) { int i; for( i = 1; i < m_point_array.Count(); i++ ) { vp.DrawPoint( m_point_array[i-1] ); vp.DrawLine( m_point_array[i-1], m_point_array[i] ); } vp.DrawPoint( m_point_array[i-1] ); vp.DrawPoint( pt ); vp.DrawLine( m_point_array[i-1], pt ); } CRhinoGetPoint::DynamicDraw( hdc, vp, pt); }
CRhinoCommand::result CCommandSampleTriangulatePolygon::RunCommand( const CRhinoCommandContext& context ) { CRhinoGetObject go; go.SetCommandPrompt( L"Select closed planar polygon to triangulate" ); go.SetGeometryFilter( CRhinoGetObject::curve_object ); go.SetGeometryFilter( CRhinoGetObject::closed_curve ); go.EnableSubObjectSelect( FALSE ); go.GetObjects( 1, 1 ); if( go.CommandResult() != CRhinoCommand::success ) return go.CommandResult(); const CRhinoObjRef& ref = go.Object(0); ON_3dPointArray vertices; const ON_PolylineCurve* pc = ON_PolylineCurve::Cast( ref.Curve() ); if( pc ) { vertices = pc->m_pline; } else { const ON_NurbsCurve* nc = ON_NurbsCurve::Cast( ref.Curve() ); if( nc ) nc->IsPolyline( &vertices ); } if( vertices.Count() < 5 ) { RhinoApp().Print( L"Curve not polygon with at least four sides.\n" ); return CRhinoCommand::nothing; } int* triangles = (int*)onmalloc( (vertices.Count()-3) * sizeof(int) * 3 ); if( 0 == triangles ) return CRhinoCommand::failure; // out of memory memset( triangles, 0, (vertices.Count()-3) * sizeof(int) * 3 ); int rc = RhinoTriangulate3dPolygon( vertices.Count()-1, 3, (const double*)vertices.Array(), 3, triangles); if( 0 == rc ) { int i; for( i = 0; i < vertices.Count()-3; i++ ) { ON_Polyline pline; pline.Append( vertices[triangles[i * 3]] ); pline.Append( vertices[triangles[i * 3 + 1]] ); pline.Append( vertices[triangles[i * 3 + 2]] ); pline.Append( pline[0] ); context.m_doc.AddCurveObject( pline ); } context.m_doc.Redraw(); } onfree( triangles ); return CRhinoCommand::success; }
int CGetPolylinePoints::GetPoints() { m_point_array.Empty(); SetCommandPrompt( L"Start of polyline" ); AcceptNothing(); CRhinoGet::result res = GetPoint(); if( res == CRhinoGet::point ) { m_point_array.Append( Point() ); SetCommandPrompt( L"Next point of polyline" ); for( ;; ) { SetBasePoint( Point() ); res = GetPoint(); if( res == CRhinoGet::point ) { ON_3dPoint pt = Point(); if( pt.DistanceTo(m_point_array[m_point_array.Count()-1]) > ON_ZERO_TOLERANCE ) m_point_array.Append( Point() ); continue; } if( res == CRhinoGet::nothing ) break; return 0; } } return m_point_array.Count(); }
CRhinoCommand::result CCommandSampleLineMeshIntersect::RunCommand( const CRhinoCommandContext& context ) { CRhinoGetObject gm; gm.SetCommandPrompt(L"Select mesh to intersect"); gm.SetGeometryFilter(CRhinoGetObject::mesh_object); gm.GetObjects(1, 1); if (gm.CommandResult() != CRhinoCommand::success) return gm.CommandResult(); const ON_Mesh* mesh = gm.Object(0).Mesh(); if (0 == mesh) return CRhinoCommand::failure; CRhinoGetObject gl; gl.SetCommandPrompt(L"Select line to intersect with"); gl.SetGeometryFilter(CRhinoGetObject::curve_object); gl.SetGeometryAttributeFilter(CRhinoGetObject::open_curve); gl.EnablePreSelect(FALSE); gl.EnableDeselectAllBeforePostSelect(FALSE); gl.GetObjects(1, 1); if (gl.CommandResult() != CRhinoCommand::success) return gl.CommandResult(); const ON_Curve* curve = gl.Object(0).Curve(); if (0 == curve) return CRhinoCommand::failure; const ON_LineCurve* line_curve = ON_LineCurve::Cast(curve); if (0 == line_curve) { RhinoApp().Print(L"Not a line curve.\n"); return CRhinoCommand::nothing; } ON_3dPointArray points; points.Append(line_curve->m_line.from); points.Append(line_curve->m_line.to); const ON_MeshTree* mesh_tree = mesh->MeshTree(true); if (mesh_tree) { ON_SimpleArray<ON_CMX_EVENT> cmx; if (mesh_tree->IntersectPolyline(2, points.Array(), cmx)) { for (int i = 0; i < cmx.Count(); i++) { RhinoApp().Print(L"Intesection found at face index = %d.\n", cmx[i].m_M[0].m_face_index); CRhinoPointObject* point_object = context.m_doc.AddPointObject(cmx[i].m_M[0].m_P); if (point_object) point_object->Select(); } context.m_doc.Redraw(); } if (1 == cmx.Count()) RhinoApp().Print(L"1 intesection found.\n"); else RhinoApp().Print(L"%d intesections found.\n", cmx.Count()); } return CRhinoCommand::success; }
void ON_TextLog::Print( const ON_3dPointArray& a, const char* sPreamble ) { const double* p = (a.Array() ? &a.Array()[0].x : NULL ); PrintPointList( 3, false, a.Count(), 3, p, sPreamble ); }
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"); }