void ON_GL( ON_Viewport& viewport, int port_left, int port_right, int port_bottom, int port_top ) { // Sets viewport's port to port_* values and adjusts frustum // so it's aspect matches the port's. ON_Xform projectionMatrix; // camera to clip transformation const int port_width = abs(port_right - port_left); const int port_height = abs(port_top - port_bottom); if ( port_width == 0 || port_height == 0 ) return; const double port_aspect = ((double)port_width)/((double)port_height); viewport.SetFrustumAspect( port_aspect ); viewport.SetScreenPort( port_left, port_right, port_bottom, port_top, 0, 0xff ); ON_BOOL32 bHaveCameraToClip = viewport.GetXform( ON::camera_cs, ON::clip_cs, projectionMatrix ); if ( bHaveCameraToClip ) { projectionMatrix.Transpose(); glMatrixMode(GL_PROJECTION); glLoadMatrixd( &projectionMatrix.m_xform[0][0] ); } }
BOOL COrientOnCrvXform::CalculateTransform( CRhinoViewport& vp, const ON_3dPoint& pt, ON_Xform& xform ) { BOOL bResult = FALSE; if( m_path_curve ) { double t = 0.0; if( m_path_curve->GetClosestPoint(pt, &t) ) { ON_3dPoint origin = m_path_curve->PointAt( t ); ON_Plane dest_plane; if( m_perp_mode ) { ON_3dVector tangent = m_path_curve->TangentAt( t ); MakeNormalPlane( origin, tangent, dest_plane ); } else { dest_plane.origin = origin; dest_plane.xaxis = m_path_curve->TangentAt( t ); dest_plane.zaxis = m_base_plane.zaxis; dest_plane.yaxis = ON_CrossProduct( dest_plane.zaxis, dest_plane.xaxis ); dest_plane.UpdateEquation(); } xform.Rotation( m_base_plane, dest_plane ); bResult = xform.IsValid() ? TRUE : FALSE; } } return bResult; }
ON_BOOL32 ON_Geometry::Scale( double x ) { if ( x == 1.0 ) return true; ON_Xform s; s.Scale( x, x, x ); return Transform( s ); }
ON_BOOL32 ON_Geometry::Translate( const ON_3dVector& delta ) { if ( delta.IsZero() ) return true; ON_Xform tr; tr.Translation( delta ); return Transform( tr ); }
bool ON_Plane::Translate( const ON_3dVector& delta ) { ON_Xform tr; tr.Translation( delta ); return Transform( tr ); }
bool ON_BezierCage::Rotate( double sin_angle, // sin(angle) double cos_angle, // cos(angle) const ON_3dVector& axis, // axis of rotation const ON_3dPoint& center // center of rotation ) { ON_Xform rot; rot.Rotation( sin_angle, cos_angle, axis, center ); return Transform( rot ); }
bool ON_Quaternion::GetRotation(ON_Xform& xform) const { ON_Plane plane; bool rc = GetRotation(plane); if (rc) xform.Rotation(ON_Plane::World_xy,plane); else if (IsZero()) xform.Zero(); else xform.Identity(); return rc; }
bool ON_Quaternion::GetRotation(ON_Xform& xform) const { bool rc; ON_Quaternion q(*this); if ( q.Unitize() ) { if ( fabs(q.a-a) <= ON_ZERO_TOLERANCE && fabs(q.b-b) <= ON_ZERO_TOLERANCE && fabs(q.c-c) <= ON_ZERO_TOLERANCE && fabs(q.d-d) <= ON_ZERO_TOLERANCE ) { // "this" was already unitized - don't tweak bits q = *this; } xform[1][0] = 2.0*(q.b*q.c + q.a*q.d); xform[2][0] = 2.0*(q.b*q.d - q.a*q.c); xform[3][0] = 0.0; xform[0][1] = 2.0*(q.b*q.c - q.a*q.d); xform[2][1] = 2.0*(q.c*q.d + q.a*q.b); xform[3][1] = 0.0; xform[0][2] = 2.0*(q.b*q.d + q.a*q.c); xform[1][2] = 2.0*(q.c*q.d - q.a*q.b); xform[3][2] = 0.0; q.b = q.b*q.b; q.c = q.c*q.c; q.d = q.d*q.d; xform[0][0] = 1.0 - 2.0*(q.c + q.d); xform[1][1] = 1.0 - 2.0*(q.b + q.d); xform[2][2] = 1.0 - 2.0*(q.b + q.c); xform[0][3] = xform[1][3] = xform[2][3] = 0.0; xform[3][3] = 1.0; rc = true; } else if ( IsZero() ) { xform.Zero(); rc = false; } else { // something is seriously wrong ON_ERROR("ON_Quaternion::GetRotation(ON_Xform) quaternion is invalid"); xform.Identity(); rc = false; } return rc; }
ON_BOOL32 ON_Geometry::Rotate( double sin_angle, // sin(angle) double cos_angle, // cos(angle) const ON_3dVector& axis, // axis of rotation const ON_3dPoint& center // center of rotation ) { if ( sin_angle == 0.0 && cos_angle == 1.0 ) return true; ON_Xform rot; rot.Rotation( sin_angle, cos_angle, axis, center ); return Transform( rot ); }
void ON_GL( const ON_Viewport& viewport ) { // sets model view matrix (world to camera transformation) ON_Xform modelviewMatrix; // world to camera transformation ON_BOOL32 bHaveWorldToCamera = viewport.GetXform( ON::world_cs, ON::camera_cs, modelviewMatrix ); if ( bHaveWorldToCamera ) { modelviewMatrix.Transpose(); glMatrixMode(GL_MODELVIEW); glLoadMatrixd( &modelviewMatrix.m_xform[0][0] ); } }
BOOL ON_Hatch::Transform( const ON_Xform& xform) { if( fabs( fabs( xform.Determinant()) - 1.0) > 1.0e-4) { // xform has a scale component ON_Plane tmp( m_plane); tmp.Transform( xform); ON_Xform A, B, T; A.Rotation( ON_xy_plane, m_plane); B.Rotation( tmp, ON_xy_plane); T = B * xform * A; // kill translation and z-scaling T[0][2] = T[0][3] = 0.0; T[1][2] = T[1][3] = 0.0; T[2][0] = T[2][1] = 0.0; T[2][2] = 1.0; T[2][3] = 0.0; T[3][0] = T[3][1] = T[3][2] = 0.0; T[3][3] = 1.0; for( int i = 0; i < LoopCount(); i++) m_loops[i]->m_p2dCurve->Transform( T); } int rc = m_plane.Transform( xform); return rc; }
ON_BOOL32 ON_PlaneSurface::Transform( const ON_Xform& xform ) { TransformUserData(xform); ON_3dPoint p = m_plane.origin + m_extents[0][0]*m_plane.xaxis + m_extents[1][0]*m_plane.yaxis; ON_3dPoint q = m_plane.origin + m_extents[0][1]*m_plane.xaxis + m_extents[1][1]*m_plane.yaxis; bool rc = m_plane.Transform( xform )?true:false; if (rc && fabs(fabs(xform.Determinant())-1.0) > ON_SQRT_EPSILON ) { p = xform*p; q = xform*q; double x0, x1, y0, y1; rc = false; if ( m_plane.ClosestPointTo(p,&x0,&y0) && m_plane.ClosestPointTo(q,&x1,&y1) ) { if ( x0 < x1 && y0 < y1 ) { m_extents[0].Set(x0,x1); m_extents[1].Set(y0,y1); rc = true; } } } return rc; }
// rotate line about a point and axis bool ON_Line::Rotate( double sin_angle, // sin(angle) double cos_angle, // cos(angle) const ON_3dVector& axis, // axis of rotation const ON_3dPoint& center // center of rotation ) { ON_Xform rot; rot.Rotation( sin_angle, cos_angle, axis, center ); const bool bFixP0 = (from==center); const bool bFixP1 = (to==center); const bool rc = Transform( rot ); if ( bFixP0 ) from = center; if ( bFixP1 ) to = center; return rc; }
ON_BOOL32 ON_InstanceRef::IsValid( ON_TextLog* text_log ) const { if ( 0 == ON_UuidCompare( m_instance_definition_uuid, ON_nil_uuid) ) { if ( text_log ) text_log->Print("ON_InstanceRef has nil m_instance_definition_uuid.\n"); return false; } ON_Xform tmp = m_xform.Inverse()*m_xform; if ( !tmp.IsIdentity( ON_InstanceRef::m_singular_xform_tol ) ) { if ( text_log ) text_log->Print("ON_InstanceRef has singular m_xform.\n"); return false; } return true; }
void CRhGLShaderProgram::SetupViewport(const ON_Viewport& vp) { ON_Xform mv; bool bHaveModeView = false; if ( m_Uniforms.rglModelViewProjectionMatrix >= 0 ) { float ModelViewProjection[16]; ON_Xform mvp; vp.GetXform( ON::world_cs, ON::clip_cs, mvp ); mvp.Transpose(); Mat4Dto4F( &mvp.m_xform[0][0], ModelViewProjection ); glUniformMatrix4fv( m_Uniforms.rglModelViewProjectionMatrix, 1, GL_FALSE, ModelViewProjection ); } if ( m_Uniforms.rglModelViewMatrix >= 0 ) { float ModelView[16]; vp.GetXform( ON::world_cs, ON::camera_cs, mv ); mv.Transpose(); bHaveModeView = true; Mat4Dto4F( &mv.m_xform[0][0], ModelView ); glUniformMatrix4fv( m_Uniforms.rglModelViewMatrix, 1, GL_FALSE, ModelView ); } if ( m_Uniforms.rglProjectionMatrix >= 0 ) { float Projection[16]; ON_Xform pr; vp.GetXform( ON::camera_cs, ON::clip_cs, pr ); pr.Transpose(); Mat4Dto4F( &pr.m_xform[0][0], Projection ); glUniformMatrix4fv( m_Uniforms.rglProjectionMatrix, 1, GL_FALSE, Projection ); } if ( m_Uniforms.rglNormalMatrix >= 0 ) { float NormalMatrix[9]; if ( !bHaveModeView ) { vp.GetXform( ON::world_cs, ON::camera_cs, mv ); mv.Transpose(); bHaveModeView = true; } Mat4Dto3F( &mv.m_xform[0][0], NormalMatrix ); glUniformMatrix3fv( m_Uniforms.rglNormalMatrix, 1, GL_FALSE, NormalMatrix ); } }
bool ON_3dPointArray::Rotate( double sin_angle, double cos_angle, const ON_3dVector& axis_of_rotation, const ON_3dPoint& center_of_rotation ) { const int count = m_count; ON_Xform rot; rot.Rotation( sin_angle, cos_angle, axis_of_rotation, center_of_rotation ); ON_SimpleArray<int> fix_index(128); int i; for ( i = 0; i < count; i++ ) { if ( m_a[i] == center_of_rotation ) fix_index.Append(i); } const bool rc = Transform( rot ); for ( i = 0; i < fix_index.Count(); i++ ) { m_a[fix_index[i]] = center_of_rotation; } return rc; }
void ON_TextLog::Print( const ON_Xform& xform ) { if ( xform.IsIdentity() ) { Print("identity transformation\n"); } else if ( xform.IsZero() ) { Print("zero transformation\n"); } else { Print(m_double4_format,xform[0][0],xform[0][1],xform[0][2],xform[0][3]); Print("\n"); Print(m_double4_format,xform[1][0],xform[1][1],xform[1][2],xform[1][3]); Print("\n"); Print(m_double4_format,xform[2][0],xform[2][1],xform[2][2],xform[2][3]); Print("\n"); Print(m_double4_format,xform[3][0],xform[3][1],xform[3][2],xform[3][3]); Print("\n"); } }
// rotate plane about a point and axis bool ON_Plane::Rotate( double sin_angle, // sin(angle) double cos_angle, // cos(angle) const ON_3dVector& axis, // axis of rotation const ON_3dPoint& center // center of rotation ) { bool rc = false; ON_Xform rot; if ( center == origin ) { rot.Rotation( sin_angle, cos_angle, axis, ON_origin ); xaxis = rot*xaxis; yaxis = rot*yaxis; zaxis = rot*zaxis; rc = UpdateEquation(); } else { rot.Rotation( sin_angle, cos_angle, axis, center ); rc = Transform( rot ); } return rc; }
// Copy the 2d curve, make it 3d, and transform it // to the 3d plane position ON_Curve* ON_Hatch::LoopCurve3d( int index) const { int count = m_loops.Count(); ON_Curve* pC = NULL; if( index >= 0 && index < count) { if( m_loops[index]->Curve()) { pC = m_loops[index]->Curve()->DuplicateCurve(); if( pC) { pC->ChangeDimension( 3); ON_Xform xf; xf.Rotation( ON_xy_plane, m_plane); pC->Transform( xf); } } } return pC; }
static void myRotateView( ON_Viewport& viewport, const ON_3dVector& axis, const ON_3dPoint& center, double angle ) { ON_Xform rot; ON_3dPoint camLoc; ON_3dVector camY, camZ; rot.Rotation( angle, axis, center ); if ( !viewport.GetCameraFrame( camLoc, NULL, camY, camZ ) ) return; camLoc = rot*camLoc; camY = rot*camY; camZ = -(rot*camZ); viewport.SetCameraLocation( camLoc ); viewport.SetCameraDirection( camZ ); viewport.SetCameraUp( camY ); ON_GL( viewport ); // update model view }
bool ON_Plane::Transform( const ON_Xform& xform ) { if ( xform.IsIdentity() ) { // 27 October 2011 Dale Lear // If the plane is valid and the transformation // is the identity, then NO changes should be // made to the plane's values. In particular // calling CreateFromFrame() can introduce // slight fuzz. // // Please discuss any changes with me. return IsValid(); } ON_3dPoint origin_pt = xform*origin; // use care tranforming vectors ON_3dVector xaxis_vec = (xform*(origin+xaxis)) - origin_pt; ON_3dVector yaxis_vec = (xform*(origin+yaxis)) - origin_pt; return CreateFromFrame( origin_pt, xaxis_vec, yaxis_vec ); }
int ON_Intersect( // returns 0 = no intersections, // 1 = one intersection, // 2 = 2 intersections // 3 = line lies on cylinder // If 0 is returned, first point is point // on line closest to cylinder and 2nd point is the point // on the sphere closest to the line. // If 1 is returned, first point is obtained by evaluating // the line and the second point is obtained by evaluating // the cylinder. const ON_Line& line, const ON_Cylinder& cylinder, // if cylinder.height[0]==cylinder.height[1], // then infinite cyl is used. Otherwise // finite cyl is used. ON_3dPoint& A, ON_3dPoint& B // intersection point(s) returned here ) { ON_BOOL32 bFiniteCyl = true; int rc = 0; const double cylinder_radius = fabs(cylinder.circle.radius); double tol = cylinder_radius*ON_SQRT_EPSILON; if ( tol < ON_ZERO_TOLERANCE ) tol = ON_ZERO_TOLERANCE; ON_Line axis; axis.from = cylinder.circle.plane.origin + cylinder.height[0]*cylinder.circle.plane.zaxis; axis.to = cylinder.circle.plane.origin + cylinder.height[1]*cylinder.circle.plane.zaxis; if ( axis.Length() <= tol ) { axis.to = cylinder.circle.plane.origin + cylinder.circle.plane.zaxis; bFiniteCyl = false; } //ON_BOOL32 bIsParallel = false; double line_t, axis_t; if ( !ON_Intersect(line,axis,&line_t,&axis_t) ) { axis.ClosestPointTo( cylinder.circle.plane.origin, &axis_t ); line.ClosestPointTo( cylinder.circle.plane.origin, &line_t ); } ON_3dPoint line_point = line.PointAt(line_t); ON_3dPoint axis_point = axis.PointAt(axis_t); double d = line_point.DistanceTo(axis_point); if ( bFiniteCyl ) { if ( axis_t < 0.0 ) axis_t = 0.0; else if ( axis_t > 1.0 ) axis_t = 1.0; axis_point = axis.PointAt(axis_t); } if ( d >= cylinder_radius-tol) { rc = ( d <= cylinder_radius+tol ) ? 1 : 0; A = line_point; ON_3dVector V = line_point - axis_point; if ( bFiniteCyl ) { V = V - (V*cylinder.circle.plane.zaxis)*cylinder.circle.plane.zaxis; } V.Unitize(); B = axis_point + cylinder_radius*V; if ( rc == 1 ) { // check for overlap ON_3dPoint P = axis.ClosestPointTo(line.from); d = P.DistanceTo(line.from); if ( fabs(d-cylinder_radius) <= tol ) { P = axis.ClosestPointTo(line.to); d = P.DistanceTo(line.to); if ( fabs(d-cylinder_radius) <= tol ) { rc = 3; A = cylinder.ClosestPointTo(line.from); B = cylinder.ClosestPointTo(line.to); } } } } else { // transform to coordinate system where equation of cyl // is x^2 + y^2 = R^2 and solve for line parameter(s). ON_Xform xform; xform.Rotation( cylinder.circle.plane, ON_xy_plane ); ON_Line L = line; L.Transform(xform); const double x0 = L.from.x; const double x1 = L.to.x; const double x1mx0 = x1-x0; double ax = x1mx0*x1mx0; double bx = 2.0*x1mx0*x0; double cx = x0*x0; const double y0 = L.from.y; const double y1 = L.to.y; const double y1my0 = y1-y0; double ay = y1my0*y1my0; double by = 2.0*y1my0*y0; double cy = y0*y0; double t0, t1; int qerc = ON_SolveQuadraticEquation(ax+ay, bx+by, cx+cy-cylinder_radius*cylinder_radius, &t0,&t1); if ( qerc == 2 ) { // complex roots - ignore (tiny) imaginary part caused by computational noise. t1 = t0; } A = cylinder.ClosestPointTo(line.PointAt(t0)); B = cylinder.ClosestPointTo(line.PointAt(t1)); d = A.DistanceTo(B); if ( d <= ON_ZERO_TOLERANCE ) { A = line_point; ON_3dVector V = line_point - axis_point; if ( bFiniteCyl ) { V = V - (V*cylinder.circle.plane.zaxis)*cylinder.circle.plane.zaxis; } V.Unitize(); B = axis_point + cylinder_radius*V; rc = 1; } else rc = 2; } return rc; }
CRhinoCommand::result CTraslRuota::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; ON_Layer currentLayer; int numLayers = layer_table.LayerCount(); for(int i = 0; i < numLayers; i++) { currentLayer = layer_table[i]; const CRhinoLayer& layer = layer_table[i]; currentLayer.SetVisible(true); layer_table.ModifyLayer(currentLayer, i); layer_table.SetCurrentLayerIndex(i); const CRhinoLayer& current_layer = layer_table.CurrentLayer(); int layer_index = layer_table.CurrentLayerIndex(); const CRhinoLayer& layer2 = layer_table[layer_index]; ON_SimpleArray<CRhinoObject*> obj_list; int j, obj_count = context.m_doc.LookupObject( layer2, obj_list ); for( j = 0; j < obj_count; j++ ) { CRhinoObject* obj = obj_list[j]; if( obj && obj->IsSelectable() ) obj->Select(); if( obj_count ) context.m_doc.Redraw(); } } context.m_doc.Redraw(); //inizio rotazione double m_angle=(_wtof(plugin.m_dialog->ValoreRotazione)); ON_Plane plane = RhinoActiveCPlane(); CRhinoGetObject go1; go1.GetObjects( 1, 0 ); int numero1 = go1.ObjectCount(); for( int k = 0; k < go1.ObjectCount(); k++ ) { // Get an object reference const CRhinoObjRef& ref = go1.Object(k); // Get the real object const CRhinoObject* obj = ref.Object(); if( !obj ) continue; ON_Xform xform; xform.Rotation( m_angle * ON_PI / 180.0, plane.zaxis, plane.Origin() ); context.m_doc.TransformObject( obj, xform, true, true, true ); context.m_doc.Redraw(); } //fine rotazione //inizio traslazione CRhinoGetObject go; int numero = go.ObjectCount(); go.GetObjects( 1, 0 ); for( int i = 0; i < go.ObjectCount(); i++ ) { // Get an object reference const CRhinoObjRef& ref = go.Object(i); // Get the real object const CRhinoObject* obj = ref.Object(); if( !obj ) continue; ON_Xform xform; xform.Rotation( m_angle * ON_PI / 180.0, plane.zaxis, plane.Origin() ); //context.m_doc.TransformObject( obj, xform, true, true, true ); context.m_doc.Redraw(); xform.Translation((_wtof(plugin.m_dialog->ValoreTraslazione)),0,0); context.m_doc.TransformObject( obj, xform, true, true, true ); context.m_doc.Redraw(); } // fine traslazione context.m_doc.Redraw(); return CRhinoCommand::success; }
bool ON_Hatch::ReplaceLoops(ON_SimpleArray<const ON_Curve*> loop_curves) { if(loop_curves.Count() < 1) return false; bool rc = true; ON_Xform xf; bool flat = false; ON_SimpleArray<ON_HatchLoop*> loops; for(int i = 0; i < loop_curves.Count(); i++) { if(loop_curves[i] == 0) { rc = false; break; } ON_Curve* p2d = loop_curves[i]->Duplicate(); if(p2d == 0) { rc = false; break; } if(p2d->Dimension() == 3) { if(!flat) { xf.PlanarProjection(m_plane); flat = true; } if(!p2d->Transform(xf) || !p2d->ChangeDimension(2)) { delete p2d; rc = false; break; } } ON_HatchLoop* loop = new ON_HatchLoop(p2d,loops.Count()?ON_HatchLoop::ltInner:ON_HatchLoop::ltOuter); if(loop) loops.Append(loop); else delete p2d; } if(!rc) { for(int i = 0; i < loops.Count(); i++) delete loops[i]; loops.Empty(); } if(loops.Count() < 1) return false; for(int i = 0; i < m_loops.Count(); i++) delete m_loops[i]; m_loops.Empty(); for(int i = 0; i < loops.Count(); i++) m_loops.Append(loops[i]); return true; }
bool ON_Arc::GetNurbFormParameterFromRadian(double RadianParameter, double* NurbParameter ) const { if(!IsValid() || NurbParameter==NULL) return false; ON_Interval ADomain = DomainRadians(); double endtol = 10.0*ON_EPSILON*(fabs(ADomain[0]) + fabs(ADomain[1])); double del = RadianParameter - ADomain[0]; if(del <= endtol && del >= -ON_SQRT_EPSILON) { *NurbParameter=ADomain[0]; return true; } else { del = ADomain[1] - RadianParameter; if(del <= endtol && del >= -ON_SQRT_EPSILON){ *NurbParameter=ADomain[1]; return true; } } if( !ADomain.Includes(RadianParameter ) ) return false; ON_NurbsCurve crv; if( !GetNurbForm(crv)) return false; //Isolate a bezier that contains the solution int cnt = crv.SpanCount(); int si =0; //get span index int ki=0; //knot index double ang = ADomain[0]; ON_3dPoint cp; cp = crv.PointAt( crv.Knot(0) ) - Center(); double x = ON_DotProduct(Plane().Xaxis(),cp); double y = ON_DotProduct(Plane().Yaxis(),cp); double at = atan2( y, x); //todo make sure we dont go to far for( si=0, ki=0; si<cnt; si++, ki+=crv.KnotMultiplicity(ki) ){ cp = crv.PointAt( crv.Knot(ki+2)) - Center(); x = ON_DotProduct(Plane().Xaxis(),cp); y = ON_DotProduct(Plane().Yaxis(),cp); double at2 = atan2(y,x); if(at2>at) ang+=(at2-at); else ang += (2*ON_PI + at2 - at); at = at2; if( ang>RadianParameter) break; } // Crash Protection trr#55679 if( ki+2>= crv.KnotCount()) { *NurbParameter=ADomain[1]; return true; } ON_Interval BezDomain(crv.Knot(ki), crv.Knot(ki+2)); ON_BezierCurve bez; if(!crv.ConvertSpanToBezier(ki,bez)) return false; ON_Xform COC; COC.ChangeBasis( ON_Plane(),Plane()); bez.Transform(COC); // change coordinates to circles local frame double a[3]; // Bez coefficients of a quadratic to solve for(int i=0; i<3; i++) a[i] = tan(RadianParameter)* bez.CV(i)[0] - bez.CV(i)[1]; //Solve the Quadratic double descrim = (a[1]*a[1]) - a[0]*a[2]; double squared = a[0]-2*a[1]+a[2]; double tbez; if(fabs(squared)> ON_ZERO_TOLERANCE){ ON_ASSERT(descrim>=0); descrim = sqrt(descrim); tbez = (a[0]-a[1] + descrim)/(a[0]-2*a[1]+a[2]); if( tbez<0 || tbez>1){ double tbez2 = (a[0]-a[1]-descrim)/(a[0] - 2*a[1] + a[2]); if( fabs(tbez2 - .5)<fabs(tbez-.5) ) tbez = tbez2; } ON_ASSERT(tbez>=-ON_ZERO_TOLERANCE && tbez<=1+ON_ZERO_TOLERANCE); } else{ // Quadratic degenerates to linear tbez = 1.0; if(a[0]-a[2]) tbez = a[0]/(a[0]-a[2]); } if(tbez<0) tbez=0.0; else if(tbez>1.0) tbez=1.0; //Debug ONLY Code - check the result // double aa = a[0]*(1-tbez)*(1-tbez) + 2*a[1]*tbez*(1-tbez) + a[2]*tbez*tbez; // double tantheta= tan(RadianParameter); // ON_3dPoint bezp; // bez.Evaluate(tbez, 0, 3, bezp); // double yx = bezp.y/bezp.x; *NurbParameter = BezDomain.ParameterAt(tbez); return true; }
bool ON_BezierCage::Scale( double x ) { ON_Xform s; s.Scale( x, x, x ); return Transform( s ); }
int ON_Intersect( const ON_Line& line, const ON_Circle& circle, double* line_t0, ON_3dPoint& circle_point0, double* line_t1, ON_3dPoint& circle_point1 ) { // transform to coordinate system where equation of circle // is x^2 + y^2 = R^2 and solve for line parameter(s). ON_Xform xform; xform.ChangeBasis( circle.plane, ON_xy_plane ); xform.ChangeBasis( ON_xy_plane, circle.plane ); ON_Line L = line; L.Transform(xform); double r = fabs(circle.radius); double tol = r*ON_SQRT_EPSILON; if ( tol < ON_ZERO_TOLERANCE ) tol = ON_ZERO_TOLERANCE; int xcnt; if ( fabs(L.from.x - L.to.x) <= tol && fabs(L.from.y - L.to.y) <= tol && fabs(L.from.z - L.to.z) > tol ) { xcnt = 0; } else { xcnt = Intersect2dLineCircle( L.from, L.to, r, tol, line_t0, line_t1 ); if ( xcnt == 3 ) xcnt = 1; } if ( xcnt == 0 ) { if ( L.ClosestPointTo( circle.Center(), line_t0 ) ) { xcnt = 1; *line_t1 = *line_t0; } } ON_3dPoint line_point1, line_point0 = line.PointAt(*line_t0); circle_point0 = circle.ClosestPointTo(line_point0); double d1, d0 = line_point0.DistanceTo(circle_point0); if ( xcnt == 2 ) { line_point1 = line.PointAt(*line_t1); circle_point1 = circle.ClosestPointTo(line_point1); d1 = line_point1.DistanceTo(circle_point1); } else { line_point1 = line_point0; circle_point1 = circle_point0; d1 = d0; } if ( xcnt==2 && (d0 > tol && d1 > tol) ) { xcnt = 1; if ( d0 <= d1 ) { *line_t1 = *line_t0; line_point1 = line_point0; circle_point1 = circle_point0; d1 = d0; } else { *line_t0 = *line_t1; line_point0 = line_point1; circle_point0 = circle_point1; d0 = d1; } } if ( xcnt == 1 && d0 > tol ) { // TODO: iterate to closest point } return xcnt; }
CRhinoCommand::result CCommandSampleOrientOnSrf::RunCommand( const CRhinoCommandContext& context ) { // Select objects to orient CRhinoGetObject go; go.SetCommandPrompt( L"Select objects to orient" ); go.EnableSubObjectSelect( FALSE ); go.EnableGroupSelect( TRUE ); go.GetObjects( 1, 0 ); if( go.CommandResult() != CRhinoCommand::success ) return go.CommandResult(); // Point to orient from CRhinoGetPoint gp; gp.SetCommandPrompt( L"Point to orient from" ); gp.GetPoint(); if( gp.CommandResult() != CRhinoCommand::success ) return gp.CommandResult(); // Define source plane CRhinoView* view = gp.View(); if( 0 == view ) { view = RhinoApp().ActiveView(); if( 0 == view ) return CRhinoCommand::failure; } ON_Plane source_plane( view->Viewport().ConstructionPlane().m_plane ); source_plane.SetOrigin( gp.Point() ); // Surface to orient on CRhinoGetObject gs; gs.SetCommandPrompt( L"Surface to orient on" ); gs.SetGeometryFilter( CRhinoGetObject::surface_object ); gs.EnableSubObjectSelect( TRUE ); gs.EnableDeselectAllBeforePostSelect( false ); gs.EnableOneByOnePostSelect(); gs.GetObjects( 1, 1 ); if( gs.CommandResult() != CRhinoCommand::success ) return gs.CommandResult(); const CRhinoObjRef& ref = gs.Object(0); // Get selected surface object const CRhinoObject* obj = ref.Object(); if( 0 == obj ) return CRhinoCommand::failure; // Get selected surface (face) const ON_BrepFace* face = ref.Face(); if( 0 == face ) return CRhinoCommand::failure; // Unselect surface obj->Select( false ); // Point on surface to orient to gp.SetCommandPrompt( L"Point on surface to orient to" ); gp.Constrain( *face ); gp.GetPoint(); if( gp.CommandResult() != CRhinoCommand::success ) return gp.CommandResult(); // Do transformation CRhinoCommand::result rc = CRhinoCommand::failure; double u = 0.0, v = 0.0; if( face->GetClosestPoint(gp.Point(), &u, &v) ) { ON_Plane target_plane; if( face->FrameAt(u, v, target_plane) ) { // If the face orientation is opposite // of natural surface orientation, then // flip the plane's zaxis. if( face->m_bRev ) target_plane.CreateFromFrame( target_plane.origin, target_plane.xaxis, -target_plane.zaxis ); // Build transformation ON_Xform xform; xform.Rotation( source_plane, target_plane ); // Do the transformation. In this example, // we will copy the original objects bool bDeleteOriginal = false; int i; for( i = 0; i < go.ObjectCount(); i++ ) context.m_doc.TransformObject( go.Object(i), xform, bDeleteOriginal ); context.m_doc.Redraw(); rc = CRhinoCommand::success; } } return rc; }
// Converts from WCS 3d points to 2d points in annotation bool ON_Annotation::GeWCStoECSXform( ON_Xform& xform ) const { ON_3dVector z = ON_CrossProduct( m_plane.xaxis, m_plane.yaxis ); return xform.ChangeBasis( ON_origin, ON_xaxis, ON_yaxis, ON_zaxis, m_plane.origin, m_plane.xaxis, m_plane.yaxis, z ); }
bool ON_BrepExtrude( ON_Brep& brep, const ON_Curve& path_curve, bool bCap ) { ON_Workspace ws; const int vcount0 = brep.m_V.Count(); const int tcount0 = brep.m_T.Count(); const int lcount0 = brep.m_L.Count(); const int ecount0 = brep.m_E.Count(); const int fcount0 = brep.m_F.Count(); const ON_3dPoint PathStart = path_curve.PointAtStart(); ON_3dPoint P = path_curve.PointAtEnd(); if ( !PathStart.IsValid() || !P.IsValid() ) return false; const ON_3dVector height = P - PathStart; if ( !height.IsValid() || height.Length() <= ON_ZERO_TOLERANCE ) return false; ON_Xform tr; tr.Translation(height); // count number of new sides int side_count = 0; int i, vi, ei, fi; bool* bSideEdge = (bool*)ws.GetIntMemory(ecount0*sizeof(bSideEdge[0])); for ( ei = 0; ei < ecount0; ei++ ) { const ON_BrepEdge& e = brep.m_E[ei]; if ( 1 == e.m_ti.Count() ) { side_count++; bSideEdge[ei] = true; } else { bSideEdge[ei] = false; } } brep.m_V.Reserve( 2*vcount0 ); i = 4*side_count + (bCap?tcount0:0); brep.m_T.Reserve( tcount0 + i ); brep.m_C2.Reserve( brep.m_C2.Count() + i ); brep.m_L.Reserve( lcount0 + side_count + (bCap?lcount0:0) ); i = side_count + (bCap?ecount0:side_count); brep.m_E.Reserve( ecount0 + i ); brep.m_C3.Reserve( brep.m_C3.Count() + i ); i = side_count + (bCap?fcount0:0); brep.m_F.Reserve( fcount0 + i ); brep.m_S.Reserve( brep.m_S.Count() + i ); bool bOK = true; // build top vertices int* topvimap = ws.GetIntMemory(vcount0); memset(topvimap,0,vcount0*sizeof(topvimap[0])); if ( bCap ) { for ( vi = 0; vi < vcount0; vi++ ) { const ON_BrepVertex& bottomv = brep.m_V[vi]; ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance); topvimap[vi] = topv.m_vertex_index; } } else { for ( ei = 0; ei < ecount0; ei++ ) { if ( bSideEdge[ei] ) { const ON_BrepEdge& bottome = brep.m_E[ei]; int bottomvi0 = bottome.m_vi[0]; if ( bottomvi0 < 0 || bottomvi0 >= vcount0 ) { bOK = false; break; } int bottomvi1 = bottome.m_vi[1]; if ( bottomvi1 < 0 || bottomvi1 >= vcount0 ) { bOK = false; break; } if ( !topvimap[bottomvi0] ) { const ON_BrepVertex& bottomv = brep.m_V[bottomvi0]; ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance); topvimap[bottomvi0] = topv.m_vertex_index; } if ( !topvimap[bottomvi1] ) { const ON_BrepVertex& bottomv = brep.m_V[bottomvi1]; ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance); topvimap[bottomvi1] = topv.m_vertex_index; } } } } // build top edges int* topeimap = ws.GetIntMemory(ecount0); memset(topeimap,0,ecount0*sizeof(topeimap[0])); if ( bOK ) for ( ei = 0; ei < ecount0; ei++ ) { if ( bCap || bSideEdge[ei] ) { const ON_BrepEdge& bottome = brep.m_E[ei]; ON_BrepVertex& topv0 = brep.m_V[topvimap[bottome.m_vi[0]]]; ON_BrepVertex& topv1 = brep.m_V[topvimap[bottome.m_vi[1]]]; ON_Curve* c3 = bottome.DuplicateCurve(); if ( !c3 ) { bOK = false; break; } c3->Transform(tr); int c3i = brep.AddEdgeCurve(c3); ON_BrepEdge& tope = brep.NewEdge(topv0,topv1,c3i,0,bottome.m_tolerance); topeimap[ei] = tope.m_edge_index; } } // build side edges int* sideveimap = ws.GetIntMemory(vcount0); memset(sideveimap,0,vcount0*sizeof(sideveimap[0])); if ( bOK ) for ( vi = 0; vi < vcount0; vi++ ) { ON_BrepVertex& bottomv = brep.m_V[vi]; for ( int vei = 0; vei < bottomv.m_ei.Count(); vei++ ) { if ( bSideEdge[bottomv.m_ei[vei]] && topvimap[vi] ) { ON_BrepVertex& topv = brep.m_V[topvimap[vi]]; ON_Curve* c3 = path_curve.DuplicateCurve(); if ( !c3 ) { bOK = false; } else { ON_3dVector D = bottomv.point - PathStart; c3->Translate(D); int c3i = brep.AddEdgeCurve(c3); const ON_BrepEdge& e = brep.NewEdge(bottomv,topv,c3i,0,0.0); sideveimap[vi] = e.m_edge_index; } break; } } } if ( bOK && bCap ) { // build top faces for (fi = 0; fi < fcount0; fi++ ) { const ON_BrepFace& bottomf = brep.m_F[fi]; ON_Surface* srf = bottomf.DuplicateSurface(); if ( !srf ) { bOK = false; break; } srf->Transform(tr); int si = brep.AddSurface(srf); ON_BrepFace& topf = brep.NewFace(si); topf.m_bRev = !bottomf.m_bRev; const int loop_count = bottomf.m_li.Count(); topf.m_li.Reserve(loop_count); for ( int fli = 0; fli < loop_count; fli++ ) { const ON_BrepLoop& bottoml = brep.m_L[bottomf.m_li[fli]]; ON_BrepLoop& topl = brep.NewLoop(bottoml.m_type,topf); const int loop_trim_count = bottoml.m_ti.Count(); topl.m_ti.Reserve(loop_trim_count); for ( int lti = 0; lti < loop_trim_count; lti++ ) { const ON_BrepTrim& bottomt = brep.m_T[bottoml.m_ti[lti]]; ON_NurbsCurve* c2 = ON_NurbsCurve::New(); if ( !bottomt.GetNurbForm(*c2) ) { delete c2; bOK = false; break; } int c2i = brep.AddTrimCurve(c2); ON_BrepTrim* topt = 0; if ( bottomt.m_ei >= 0 ) { ON_BrepEdge& tope = brep.m_E[topeimap[bottomt.m_ei]]; topt = &brep.NewTrim(tope,bottomt.m_bRev3d,topl,c2i); } else { // singular trim ON_BrepVertex& topv = brep.m_V[topvimap[bottomt.m_vi[0]]]; topt = &brep.NewSingularTrim(topv,topl,bottomt.m_iso,c2i); } topt->m_tolerance[0] = bottomt.m_tolerance[0]; topt->m_tolerance[1] = bottomt.m_tolerance[1]; topt->m_pbox = bottomt.m_pbox; topt->m_type = bottomt.m_type; topt->m_iso = bottomt.m_iso; } topl.m_pbox = bottoml.m_pbox; } } } // build sides int bRev3d[4] = {0,0,1,1}; int vid[4], eid[4]; if( bOK ) for ( ei = 0; ei < ecount0; ei++ ) { if ( bSideEdge[ei] && topeimap[ei] ) { ON_BrepEdge& bottome = brep.m_E[ei]; ON_BrepEdge& tope = brep.m_E[topeimap[ei]]; vid[0] = bottome.m_vi[0]; vid[1] = bottome.m_vi[1]; vid[2] = topvimap[vid[1]]; vid[3] = topvimap[vid[0]]; if ( sideveimap[vid[0]] && sideveimap[vid[1]] ) { ON_BrepEdge& leftedge = brep.m_E[sideveimap[vid[0]]]; ON_BrepEdge& rightedge = brep.m_E[sideveimap[vid[1]]]; ON_Curve* cx = bottome.DuplicateCurve(); if ( !cx ) { bOK = false; break; } ON_Curve* cy = leftedge.DuplicateCurve(); if ( !cy ) { delete cx; bOK = false; break; } ON_SumSurface* srf = new ON_SumSurface(); srf->m_curve[0] = cx; srf->m_curve[1] = cy; srf->m_basepoint = srf->m_curve[1]->PointAtStart(); srf->m_basepoint.x = -srf->m_basepoint.x; srf->m_basepoint.y = -srf->m_basepoint.y; srf->m_basepoint.z = -srf->m_basepoint.z; eid[0] = bottome.m_edge_index; eid[1] = rightedge.m_edge_index; eid[2] = tope.m_edge_index; eid[3] = leftedge.m_edge_index; ON_BrepFace* face = brep.NewFace(srf,vid,eid,bRev3d); if ( !face ) { bOK = false; break; } else if ( bottome.m_ti.Count() == 2 ) { const ON_BrepTrim& trim0 = brep.m_T[bottome.m_ti[0]]; const ON_BrepTrim& trim1 = brep.m_T[bottome.m_ti[1]]; const ON_BrepLoop& loop0 = brep.m_L[trim0.m_li]; const ON_BrepLoop& loop1 = brep.m_L[trim1.m_li]; bool bBottomFaceRev = brep.m_F[(loop0.m_fi != face->m_face_index) ? loop0.m_fi : loop1.m_fi].m_bRev; bool bSideFaceRev = ( trim0.m_bRev3d != trim1.m_bRev3d ) ? bBottomFaceRev : !bBottomFaceRev; face->m_bRev = bSideFaceRev; } } } } if ( !bOK ) { for ( vi = brep.m_V.Count(); vi >= vcount0; vi-- ) { brep.DeleteVertex(brep.m_V[vi]); } } return bOK; }