HeeksObj *VectorFont::Glyph::GlyphArc::Sketch( const gp_Pnt & location, const gp_Trsf & transformation_matrix, const float width, COrientationModifier *pOrientationModifier ) const { double start[3]; double end[3]; double centre[3]; double up[3]; gp_Pnt centre_point( location.X() + m_xcentre, location.Y() + m_ycentre, location.Z() ); gp_Pnt start_point( centre_point.X() + m_radius, centre_point.Y(), centre_point.Z() ); gp_Pnt end_point( centre_point.X() + m_radius, centre_point.Y(), centre_point.Z() ); gp_Dir z_direction( 0, 0, 1 ); if (pOrientationModifier) centre_point = pOrientationModifier->Transform(transformation_matrix, location.Distance(gp_Pnt(0.0,0.0,0.0)), centre_point, width ); if (pOrientationModifier) start_point = pOrientationModifier->Transform(transformation_matrix, location.Distance(gp_Pnt(0.0,0.0,0.0)), start_point, width ); gp_Trsf start_rotation_matrix; start_rotation_matrix.SetRotation( gp_Ax1(centre_point, z_direction), m_start_angle ); start_point.Transform(start_rotation_matrix); // Rotate to start_angle start[0] = start_point.X(); start[1] = start_point.Y(); start[2] = start_point.Z(); if (pOrientationModifier) end_point = pOrientationModifier->Transform(transformation_matrix, location.Distance(gp_Pnt(0.0,0.0,0.0)), end_point, width ); gp_Trsf end_rotation_matrix; end_rotation_matrix.SetRotation( gp_Ax1(centre_point, z_direction), m_end_angle ); end_point.Transform(end_rotation_matrix); // Rotate to start_angle end[0] = end_point.X(); end[1] = end_point.Y(); end[2] = end_point.Z(); centre[0] = centre_point.X(); centre[1] = centre_point.Y(); centre[2] = centre_point.Z(); gp_Pnt up_point( 0.0, 0.0, 1.0 ); // For counter-clockwise (always in this font format) up[0] = up_point.X(); up[1] = up_point.Y(); up[2] = up_point.Z(); HeeksObj *arc = heekscad_interface.NewArc( start, end, centre, up ); double m[16]; extract(transformation_matrix,m); arc->ModifyByMatrix(m); return(arc); } // End Sketch() method
void HeeksDxfRead::OnReadInsert(const char* block_name, const double* insert_point, double rotation_angle) { if (m_blocks.find( wxString(Ctt(block_name)) ) == m_blocks.end()) { return; // block not foundblock_name, const double* insert_point, double rotation_angle } else { BlockName_t b_name = wxString(Ctt(block_name)); #if 0 // insert an insert object. To be expanded at the end HInsert* new_object = new HInsert(block_name, insert_point, rotation_angle); AddObject(new_object); #else CSketch* block = m_blocks[b_name]; CSketch* block_copy = new CSketch(*block); gp_Trsf tm; tm.SetTranslationPart(make_vector(insert_point)); gp_Trsf rm; rm.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), rotation_angle * 0.01745329251994329); double m[16]; extract(tm * rm, m); block_copy->ModifyByMatrix(m); AddObject(block_copy); #endif inserted_blocks.insert(b_name); } }
std::list<gp_Pnt> VectorFont::Glyph::GlyphArc::Interpolate(const gp_Pnt & location, const unsigned int number_of_points ) const { std::list<gp_Pnt> points; gp_Pnt origin(location); origin.SetX( origin.X() + m_xcentre ); origin.SetY( origin.Y() + m_ycentre ); double start_angle = m_start_angle; double end_angle = m_end_angle; if (start_angle > end_angle) { end_angle += (2 * M_PI); } double increment = (end_angle - start_angle) / number_of_points; gp_Dir z_direction( 0, 0, 1 ); for (double angle = start_angle; angle <= end_angle; angle += increment) { gp_Pnt point( location.X() + m_xcentre + m_radius, location.Y() + m_ycentre, location.Z() ); gp_Trsf rotation_matrix; rotation_matrix.SetRotation( gp_Ax1(origin, z_direction), angle ); point.Transform(rotation_matrix); points.push_back(point); } return(points); }
/* Creates the hyperboloid using a formula. TODO: Update this so the hyperboloid actually represents a proper parametric model. */ TopoDS_Shape hyperboloid::create(double innerRadius, double height, double heightUnder, double angle) { int detail = 40; gp_Pnt Origin(0,0,0); gp_Vec Dir(0,0,1); int uCount = detail; double a = innerRadius; double c = angle; double totalHeight = height + heightUnder; TColgp_Array1OfPnt array (0,uCount - 1); for (double u = 0; u < uCount; u++) { double uValue = ((totalHeight * u / (uCount - 1)) - heightUnder) / c; double vValue = 0; double sqrMe = 1 + uValue * uValue; double x = a * sqrt(sqrMe) * cos(vValue); double y = a * sqrt(sqrMe) * sin(vValue); double z = c * uValue; gp_Pnt P1(x,y,z); array.SetValue(u,P1); } Handle(Geom_BSplineCurve) hyperbola = GeomAPI_PointsToBSpline(array).Curve(); TopoDS_Edge hyperbolaTopoDS = BRepBuilderAPI_MakeEdge(hyperbola); gp_Ax1 axis = gp_Ax1(Origin,Dir); TopoDS_Shape hyperboloid = BRepPrimAPI_MakeRevol(hyperbolaTopoDS, axis); return hyperboloid; }
void HeeksDxfRead::OnReadEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool dir) { gp_Dir up(0, 0, 1); if(!dir)up = -up; gp_Pnt pc = make_point(c); gp_Elips ellipse(gp_Ax2(pc, up), major_radius, minor_radius); ellipse.Rotate(gp_Ax1(pc,up),rotation); HEllipse* new_object = new HEllipse(ellipse, start_angle, end_angle, ActiveColorPtr(m_aci)); AddObject(new_object); }
bool PCBMODEL::getModelLocation( bool aBottom, DOUBLET aPosition, double aRotation, TRIPLET aOffset, TRIPLET aOrientation, TopLoc_Location& aLocation ) { // Order of operations: // a. aOrientation is applied -Z*-Y*-X // b. aOffset is applied // Top ? add thickness to the Z offset // c. Bottom ? Rotate on X axis (in contrast to most ECAD which mirror on Y), // then rotate on +Z // Top ? rotate on -Z // d. aPosition is applied // // Note: Y axis is inverted in KiCad gp_Trsf lPos; lPos.SetTranslation( gp_Vec( aPosition.x, -aPosition.y, 0.0 ) ); // offset (inches) aOffset.x *= 25.4; aOffset.y *= 25.4; aOffset.z *= 25.4 + BOARD_OFFSET; gp_Trsf lRot; if( aBottom ) { lRot.SetRotation( gp_Ax1( gp_Pnt( 0.0, 0.0, 0.0 ), gp_Dir( 0.0, 0.0, 1.0 ) ), aRotation ); lPos.Multiply( lRot ); lRot.SetRotation( gp_Ax1( gp_Pnt( 0.0, 0.0, 0.0 ), gp_Dir( 1.0, 0.0, 0.0 ) ), M_PI ); lPos.Multiply( lRot ); } else { aOffset.z += m_thickness; lRot.SetRotation( gp_Ax1( gp_Pnt( 0.0, 0.0, 0.0 ), gp_Dir( 0.0, 0.0, 1.0 ) ), aRotation ); lPos.Multiply( lRot ); } gp_Trsf lOff; lOff.SetTranslation( gp_Vec( aOffset.x, aOffset.y, aOffset.z ) ); lPos.Multiply( lOff ); gp_Trsf lOrient; lOrient.SetRotation( gp_Ax1( gp_Pnt( 0.0, 0.0, 0.0 ), gp_Dir( 0.0, 0.0, 1.0 ) ), -aOrientation.z ); lPos.Multiply( lOrient ); lOrient.SetRotation( gp_Ax1( gp_Pnt( 0.0, 0.0, 0.0 ), gp_Dir( 0.0, 1.0, 0.0 ) ), -aOrientation.y ); lPos.Multiply( lOrient ); lOrient.SetRotation( gp_Ax1( gp_Pnt( 0.0, 0.0, 0.0 ), gp_Dir( 1.0, 0.0, 0.0 ) ), -aOrientation.x ); lPos.Multiply( lOrient ); aLocation = TopLoc_Location( lPos ); return true; }
void HeeksDxfRead::OnReadDimension(int dimension_type, double angle, double angle2, double angle3, double radius_leader_length, const double *def_point, const double *mid, const double *p1, const double *p2, const double *p3, const double *p4, const double *p5) { int type = (dimension_type & 0x07); gp_Pnt d = make_point(def_point); gp_Pnt m = make_point(mid); gp_Vec d_to_m = make_vector(d, m); gp_Pnt e = gp_Pnt(m.XYZ() + d_to_m.XYZ()); gp_Dir forward(1,0,0); HeeksColor c(0, 0, 0); if(type == 0) { forward.Rotate(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), (angle/* + angle2 + angle3*/) * -0.01745329251); } else { forward = gp_Dir(-d_to_m); c = HeeksColor(255, 0, 0); } gp_Dir left(-forward.Y(), forward.X(), 0.0); double arrow_size = 5.0; gp_Pnt da1 = d.XYZ() + forward.XYZ() * (-arrow_size) + left.XYZ() * (arrow_size * 0.25); gp_Pnt da2 = d.XYZ() + forward.XYZ() * (-arrow_size) + left.XYZ() * (arrow_size * -0.25); gp_Pnt ea1 = e.XYZ() + forward.XYZ() * (arrow_size) + left.XYZ() * (arrow_size * 0.25); gp_Pnt ea2 = e.XYZ() + forward.XYZ() * (arrow_size) + left.XYZ() * (arrow_size * -0.25); AddObject(new HLine(d, da1, &c)); AddObject(new HLine(da1, da2, &c)); AddObject(new HLine(da2, d, &c)); AddObject(new HLine(e, ea1, &c)); AddObject(new HLine(ea1, ea2, &c)); AddObject(new HLine(ea2, e, &c)); }
void LVPS_GM2Displacement1Rotation::Calculate(LVPS_XYZNode* nodes) { double xi = (nodes[DisplacementNodeX.ID].S); double yi = (nodes[DisplacementNodeY.ID].S); gp_Vec vec; vec = gp_Vec(1,0,0)*xi; aTrsf.SetTranslation(vec); vec = gp_Vec(0,1,0)*yi; gp_Trsf trsf, trsf1; trsf.SetTranslation(vec); aTrsf=trsf*aTrsf; Standard_Real X=x+nodes[DisplacementNodeX.ID].S; Standard_Real Y=y+nodes[DisplacementNodeY.ID].S; trsf1.SetRotation(gp_Ax1(gp_Pnt(X,Y,0),/*axisZ*/gp_Dir(0,0,1)),nodes[RotationNode.ID].S); aTrsf=trsf1*aTrsf; };
HeeksObj* CreateExtrusionOrRevolution(std::list<HeeksObj*> list, double height_or_angle, bool solid_if_possible, bool revolution_not_extrusion, double taper_angle_for_extrusion, bool add_new_objects) { std::list<TopoDS_Shape> faces_or_wires; ConvertToFaceOrWire(list, faces_or_wires, (fabs(taper_angle_for_extrusion) <= 0.0000001) && solid_if_possible); std::list<TopoDS_Shape> new_shapes; gp_Trsf trsf = wxGetApp().GetDrawMatrix(false); if(revolution_not_extrusion) { CreateRevolutions(faces_or_wires, new_shapes, gp_Ax1(gp_Pnt(0, 0, 0).Transformed(trsf), gp_Vec(1, 0, 0).Transformed(trsf)), height_or_angle); } else { CreateExtrusions(faces_or_wires, new_shapes, gp_Vec(0, 0, height_or_angle).Transformed(trsf), taper_angle_for_extrusion, solid_if_possible); } HeeksObj* new_object = 0; if(new_shapes.size() > 0) { for(std::list<TopoDS_Shape>::iterator It = new_shapes.begin(); It != new_shapes.end(); It++){ TopoDS_Shape& shape = *It; new_object = CShape::MakeObject(shape, revolution_not_extrusion ? _("Revolved Solid") : _("Extruded Solid"), SOLID_TYPE_UNKNOWN, wxGetApp().current_color, 1.0f); if(add_new_objects) wxGetApp().AddUndoably(new_object, NULL, NULL); else break; } } for(std::list<TopoDS_Shape>::iterator It = faces_or_wires.begin(); It != faces_or_wires.end(); It++) { TopoDS_Shape shape = *It; shape.Free(); } return new_object; }
void HGear::SetSegmentsVariables(void(*callbackfunc)(const double *p))const { callbackfunc_for_point = callbackfunc; gear_for_point = this; gp_Trsf rotation; rotation.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), m_angle * M_PI/180); mat_for_point = make_matrix(m_pos.Location(), m_pos.XDirection(), m_pos.YDirection()); mat_for_point = rotation.Multiplied(mat_for_point); cone_sin_for_point = sin(m_cone_half_angle); cone_cos_for_point = cos(m_cone_half_angle); pitch_radius = (double)(m_module * m_num_teeth)/2; inside_radius = pitch_radius - m_dedendum_multiplier*m_module; outside_radius = pitch_radius + (m_addendum_multiplier*m_module + m_addendum_offset); base_radius = pitch_radius * cos(gear_for_point->m_pressure_angle) / cos(gear_for_point->m_cone_half_angle); if(inside_radius < base_radius)inside_radius = base_radius; inside_phi_and_angle = involute_intersect(inside_radius); outside_phi_and_angle = involute_intersect(outside_radius); tip_relief_phi_and_angle = involute_intersect(outside_radius - m_tip_relief); middle_phi_and_angle = involute_intersect(pitch_radius); spline_points_for_gear.clear(); }
/** take the input point move it 'distance' back along X determine the overall sketch length determine the distance along the sketch for this character based on the distance along the text as well as the justification find the point along the sketch for this character find the angle of rotation at this point along the sketch rotate the point about this character's origin translate the point to align it with the point along the sketch. return this adjusted point location. */ gp_Pnt & COrientationModifier::Transform(gp_Trsf existing_transformation, const double _distance, gp_Pnt & point, const float width ) { double tolerance = wxGetApp().m_geom_tol; gp_Pnt original_location(point); if (m_edges.size() == 0) { // No children so no modification of position. point = original_location; return(point); } // The text is formatted as though the characters start at the origin (0,0,0) and move // to the right by the character and/or word spacing as subsequent characters are rendered. // This step moves this character so that its origin is at the (0,0,0) location so that // we rotate just this character about its origin. We can use the _distance value as // the offset along the X axis at which point this character's origin is located. gp_Pnt origin(0.0, 0.0, 0.0); gp_Trsf move_to_origin; move_to_origin.SetTranslation(origin, gp_Pnt(-1.0 * _distance, 0.0, 0.0)); point.Transform(move_to_origin); // Make sure it's positive. double distance(_distance); if (distance < 0) distance *= -1.0; // Now adjust the distance based on a combination of the justification and how far through // the text string we are. double distance_remaining = distance; switch (m_params.m_justification) { case COrientationModifierParams::eLeftJustified: if (SketchIsClosed()) { // Centre the text on the left edge. NOTE: This assumes that it's a circle with // the starting location in the positive X axis. distance_remaining = (m_total_edge_length / 2.0) - (width / 2.0) + distance; } else { distance_remaining = distance; // No special adjustment required. } break; case COrientationModifierParams::eRightJustified: if (SketchIsClosed()) { distance_remaining = m_total_edge_length - (width / 2.0) + distance; } else { distance_remaining = m_total_edge_length - width + distance; } break; case COrientationModifierParams::eCentreJustified: distance_remaining = (m_total_edge_length / 2.0) - (width / 2.0) + distance; break; case COrientationModifierParams::eTopJustified: distance_remaining = (m_total_edge_length / 4.0) - (width / 2.0) + distance; break; case COrientationModifierParams::eBottomJustified: distance_remaining = (m_total_edge_length * 3.0 / 4.0) - (width / 2.0) + distance; break; } // End switch while ((distance_remaining > tolerance) && (m_edges.size() > 0)) { for (Edges_t::iterator itEdge = m_edges.begin(); itEdge != m_edges.end(); itEdge++) { double edge_length = itEdge->second; if (edge_length < distance_remaining) { distance_remaining -= edge_length; } else { // The point we're after is along this edge somewhere. Find the point and // the first derivative at that point. The vector returned will allow us to // find out what angle the sketch is at this point. We can use this angle // to rotate the character. BRepAdaptor_Curve curve(itEdge->first); gp_Pnt p; gp_Vec vec; double proportion = distance_remaining / edge_length; Standard_Real U = ((curve.LastParameter() - curve.FirstParameter()) * proportion) + curve.FirstParameter(); curve.D1(U, p, vec); double angle = 0.0; if (m_params.m_sketch_rotates_text) { // Measure the angle with respect to the positive X axis (when looking down from the top) gp_Vec x_axis(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)); gp_Vec from_top_down( gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(0.0, 0.0, 1.0)); angle = x_axis.AngleWithRef(vec, from_top_down); } // If the user wants each character given an extra quarter turn (or more) // then add this in now. if (m_params.m_number_of_rotations > 0) { for (int i=0; i<m_params.m_number_of_rotations; i++) { angle += (PI / 2.0); } } else { for (int i=m_params.m_number_of_rotations; i<0; i++) { angle -= (PI / 2.0); } } // Rotate the point around the origin. angle *= -1.0; gp_Trsf transformation; transformation.SetRotation( gp_Ax1(origin, gp_Vec(0,0,-1)), angle ); point.Transform( transformation ); // And then translate the point from the origin to the point along the sketch. gp_Trsf around; around.SetTranslation(origin, p); point.Transform(around); return(point); } } // End for } // End while return(point); }
QString Dr=*(parameterList["PARIMD0"]); x=LVPS_Utility::ToDouble(Dr); Dr=*(parameterList["PARIMD1"]); y=LVPS_Utility::ToDouble(Dr); Dr=*(parameterList["PARIMD2"]); double length=LVPS_Utility::ToDouble(Dr); Dr=*(parameterList["PARIMD3"]); double con=LVPS_Utility::ToDouble(Dr); gp_Pnt A=gp_Pnt(x+length/2,y,0); gp_Pnt B=gp_Pnt(x-length/2,y,0); TopoDS_Edge aEdge1 = BRepBuilderAPI_MakeEdge(A , B); Shape = BRepBuilderAPI_MakeWire(aEdge1); gp_Trsf trsf; trsf.SetRotation(gp_Ax1(gp_Pnt(x,y,0),gp_Dir(0,0,1)),con); Shape = BRepBuilderAPI_Transform(Shape,trsf); myAISShape = new AIS_Shape (Shape); myAISShape->SetMaterial (Graphic3d_NOM_PLASTIC); SetColor(myAISShape); return 0; }; LVPS_GraphicModel* LVPS_Lined::Clone() { return (LVPS_GraphicModel*)(new LVPS_Lined()); }
static void AddPolyLinePoint(CDxfRead* dxf_read, double x, double y, bool bulge_found, double bulge, bool undoably) { if(poly_prev_found) { bool arc_done = false; if(poly_prev_bulge_found) { double dx = x - poly_prev_x; double dy = y - poly_prev_y; double c = sqrt(dx*dx + dy*dy); double a = atan(fabs(poly_prev_bulge))*4; //find radius of circle that for arc of angle a, has chord length c double r = (c/2) / cos((Pi-a)/2); double d = sqrt(r*r - (c/2)*(c/2)); double ps[3] = {poly_prev_x, poly_prev_y, 0}; double pe[3] = {x, y, 0}; gp_Pnt pPnt = make_point(ps); gp_Pnt nPnt = make_point(pe); gp_Dir dir(nPnt.XYZ()-pPnt.XYZ()); gp_Pnt mid = pPnt.XYZ() + dir.XYZ() * c / 2; dir.Rotate(gp_Ax1(gp_Pnt(0,0,0),gp_Dir(0,0,1)),Pi/2); gp_Pnt off; if(poly_prev_bulge >= 0) off = mid.XYZ() + dir.XYZ() * (d); else off = mid.XYZ() + dir.XYZ() * (-d); double pc[3]; extract(off,pc); dxf_read->OnReadArc(ps, pe, pc, poly_prev_bulge >= 0, undoably); arc_done = true; } if(!arc_done) { double s[3] = {poly_prev_x, poly_prev_y, 0}; double e[3] = {x, y, 0}; dxf_read->OnReadLine(s, e, undoably); } } poly_prev_found = true; poly_prev_x = x; poly_prev_y = y; if(!poly_first_found) { poly_first_x = x; poly_first_y = y; poly_first_found = true; } poly_prev_bulge_found = bulge_found; poly_prev_bulge = bulge; }
//======================================================================= //function : MergeEdges //purpose : auxilary //======================================================================= static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges, const TopoDS_Face& aFace, const Standard_Real Tol, TopoDS_Edge& anEdge) { // make chain for union BRep_Builder B; ShapeAnalysis_Edge sae; TopoDS_Edge FirstE = TopoDS::Edge(SeqEdges.Value(1)); TopoDS_Edge LastE = FirstE; TopoDS_Vertex VF = sae.FirstVertex(FirstE); TopoDS_Vertex VL = sae.LastVertex(LastE); TopTools_SequenceOfShape aChain; aChain.Append(FirstE); TColStd_MapOfInteger IndUsedEdges; IndUsedEdges.Add(1); Standard_Integer j; for(j=2; j<=SeqEdges.Length(); j++) { for(Standard_Integer k=2; k<=SeqEdges.Length(); k++) { if(IndUsedEdges.Contains(k)) continue; TopoDS_Edge edge = TopoDS::Edge(SeqEdges.Value(k)); TopoDS_Vertex VF2 = sae.FirstVertex(edge); TopoDS_Vertex VL2 = sae.LastVertex(edge); if(sae.FirstVertex(edge).IsSame(VL)) { aChain.Append(edge); LastE = edge; VL = sae.LastVertex(LastE); IndUsedEdges.Add(k); } else if(sae.LastVertex(edge).IsSame(VF)) { aChain.Prepend(edge); FirstE = edge; VF = sae.FirstVertex(FirstE); IndUsedEdges.Add(k); } } } if(aChain.Length()<SeqEdges.Length()) { MESSAGE ("can not create correct chain..."); return Standard_False; } // union edges in chain // first step: union lines and circles TopLoc_Location Loc; Standard_Real fp1,lp1,fp2,lp2; for(j=1; j<aChain.Length(); j++) { TopoDS_Edge edge1 = TopoDS::Edge(aChain.Value(j)); Handle(Geom_Curve) c3d1 = BRep_Tool::Curve(edge1,Loc,fp1,lp1); if(c3d1.IsNull()) break; while(c3d1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d1); c3d1 = tc->BasisCurve(); } TopoDS_Edge edge2 = TopoDS::Edge(aChain.Value(j+1)); Handle(Geom_Curve) c3d2 = BRep_Tool::Curve(edge2,Loc,fp2,lp2); if(c3d2.IsNull()) break; while(c3d2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d2); c3d2 = tc->BasisCurve(); } if( c3d1->IsKind(STANDARD_TYPE(Geom_Line)) && c3d2->IsKind(STANDARD_TYPE(Geom_Line)) ) { // union lines Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(c3d1); Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(c3d2); gp_Dir Dir1 = L1->Position().Direction(); gp_Dir Dir2 = L2->Position().Direction(); //if(!Dir1.IsEqual(Dir2,Precision::Angular())) { //if(!Dir1.IsParallel(Dir2,Precision::Angular())) { if(!Dir1.IsParallel(Dir2,Tol)) { continue; } // can union lines => create new edge TopoDS_Vertex V1 = sae.FirstVertex(edge1); gp_Pnt PV1 = BRep_Tool::Pnt(V1); TopoDS_Vertex V2 = sae.LastVertex(edge2); gp_Pnt PV2 = BRep_Tool::Pnt(V2); gp_Vec Vec(PV1,PV2); Handle(Geom_Line) L = new Geom_Line(gp_Ax1(PV1,Vec)); Standard_Real dist = PV1.Distance(PV2); Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(L,0.0,dist); TopoDS_Edge E; B.MakeEdge (E,tc,Precision::Confusion()); B.Add (E,V1); B.Add (E,V2); B.UpdateVertex(V1, 0., E, 0.); B.UpdateVertex(V2, dist, E, 0.); //ShapeFix_Edge sfe; //sfe.FixAddPCurve(E,aFace,Standard_False); //sfe.FixSameParameter(E); aChain.Remove(j); aChain.SetValue(j,E); j--; } if( c3d1->IsKind(STANDARD_TYPE(Geom_Circle)) && c3d2->IsKind(STANDARD_TYPE(Geom_Circle)) ) { // union circles Handle(Geom_Circle) C1 = Handle(Geom_Circle)::DownCast(c3d1); Handle(Geom_Circle) C2 = Handle(Geom_Circle)::DownCast(c3d2); gp_Pnt P01 = C1->Location(); gp_Pnt P02 = C2->Location(); if (P01.Distance(P02) > Precision::Confusion()) continue; // can union circles => create new edge TopoDS_Vertex V1 = sae.FirstVertex(edge1); gp_Pnt PV1 = BRep_Tool::Pnt(V1); TopoDS_Vertex V2 = sae.LastVertex(edge2); gp_Pnt PV2 = BRep_Tool::Pnt(V2); TopoDS_Vertex VM = sae.LastVertex(edge1); gp_Pnt PVM = BRep_Tool::Pnt(VM); GC_MakeCircle MC (PV1,PVM,PV2); Handle(Geom_Circle) C = MC.Value(); TopoDS_Edge E; if (!MC.IsDone() || C.IsNull()) { // jfa for Mantis issue 0020228 if (PV1.Distance(PV2) > Precision::Confusion()) continue; // closed chain C = C1; B.MakeEdge (E,C,Precision::Confusion()); B.Add(E,V1); B.Add(E,V2); } else { gp_Pnt P0 = C->Location(); gp_Dir D1(gp_Vec(P0,PV1)); gp_Dir D2(gp_Vec(P0,PV2)); Standard_Real fpar = C->XAxis().Direction().Angle(D1); if(fabs(fpar)>Precision::Confusion()) { // check orientation gp_Dir ND = C->XAxis().Direction().Crossed(D1); if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { fpar = -fpar; } } Standard_Real lpar = C->XAxis().Direction().Angle(D2); if(fabs(lpar)>Precision::Confusion()) { // check orientation gp_Dir ND = C->XAxis().Direction().Crossed(D2); if(ND.IsOpposite(C->Axis().Direction(),Precision::Confusion())) { lpar = -lpar; } } if(lpar<fpar) lpar += 2*M_PI; Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(C,fpar,lpar); B.MakeEdge (E,tc,Precision::Confusion()); B.Add(E,V1); B.Add(E,V2); B.UpdateVertex(V1, fpar, E, 0.); B.UpdateVertex(V2, lpar, E, 0.); } aChain.Remove(j); aChain.SetValue(j,E); j--; } } if (j < aChain.Length()) { MESSAGE ("null curve3d in edge..."); return Standard_False; } if (aChain.Length() > 1) { // second step: union edges with various curves // skl for bug 0020052 from Mantis: perform such unions // only if curves are bspline or bezier bool NeedUnion = true; for(j=1; j<=aChain.Length(); j++) { TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j)); Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,Loc,fp1,lp1); if(c3d.IsNull()) continue; while(c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) { Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c3d); c3d = tc->BasisCurve(); } if( ( c3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) || c3d->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ) ) continue; NeedUnion = false; break; } if(NeedUnion) { MESSAGE ("can not make analitical union => make approximation"); TopoDS_Wire W; B.MakeWire(W); for(j=1; j<=aChain.Length(); j++) { TopoDS_Edge edge = TopoDS::Edge(aChain.Value(j)); B.Add(W,edge); } Handle(BRepAdaptor_HCompCurve) Adapt = new BRepAdaptor_HCompCurve(W); Approx_Curve3d Conv(Adapt,Tol,GeomAbs_C1,9,1000); Handle(Geom_BSplineCurve) bc = Conv.Curve(); TopoDS_Edge E; B.MakeEdge (E,bc,Precision::Confusion()); B.Add (E,VF); B.Add (E,VL); aChain.SetValue(1,E); } else { MESSAGE ("can not make approximation for such types of curves"); return Standard_False; } } anEdge = TopoDS::Edge(aChain.Value(1)); return Standard_True; }
//static void TransformTools::Mirror(bool copy) { // pick items if(wxGetApp().m_marked_list->size() == 0){ wxGetApp().PickObjects(_("Pick objects to mirror")); } if(wxGetApp().m_marked_list->size() == 0)return; if(copy) { // check for uncopyable objects RemoveUncopyable(); if(wxGetApp().m_marked_list->size() == 0)return; } // clear the selection std::list<HeeksObj *> selected_items = wxGetApp().m_marked_list->list(); wxGetApp().m_marked_list->Clear(true); // pick a line to mirror about bool line_found = false; gp_Lin line; int save_filter = wxGetApp().m_marked_list->m_filter; wxGetApp().PickObjects(_("Pick line to mirror about"), MARKING_FILTER_LINE | MARKING_FILTER_ILINE, true); wxGetApp().m_marked_list->m_filter = save_filter; for(std::list<HeeksObj *>::const_iterator It = wxGetApp().m_marked_list->list().begin(); It != wxGetApp().m_marked_list->list().end(); It++) { HeeksObj* object = *It; if(object->GetType() == LineType) { line = ((HLine*)object)->GetLine(); line_found = true; } else if(object->GetType() == ILineType) { line = ((HILine*)object)->GetLine(); line_found = true; } } if(!line_found)return; // transform the objects wxGetApp().CreateUndoPoint(); gp_Trsf mat; mat.SetMirror(gp_Ax1(line.Location(), line.Direction())); double m[16]; extract(mat, m); if(copy) { for(std::list<HeeksObj*>::iterator It = selected_items.begin(); It != selected_items.end(); It++) { HeeksObj* object = *It; HeeksObj* new_object = object->MakeACopy(); #ifdef MULTIPLE_OWNERS object->HEEKSOBJ_OWNER->Add(new_object, NULL); #else object->m_owner->Add(new_object, NULL); #endif new_object->ModifyByMatrix(m); } wxGetApp().m_marked_list->Clear(true); } else { wxGetApp().Transform(selected_items, m); } wxGetApp().Changed(); }
//static void TransformTools::Rotate(bool copy) { //rotation axis - Z axis by default gp_Dir axis_Dir = gp_Dir(0,0,1); gp_Pnt line_Pos = gp_Pnt(0,0,0); // pick items if(wxGetApp().m_marked_list->size() == 0){ wxGetApp().PickObjects(_("Pick objects to rotate")); } if(wxGetApp().m_marked_list->size() == 0)return; // get number of copies HeeksConfig config; int ncopies; config.Read(_T("RotateNumCopies"), &ncopies, 1); if(copy) { // check for uncopyable objects RemoveUncopyable(); if(wxGetApp().m_marked_list->size() == 0)return; } // clear the selection std::list<HeeksObj *> selected_items = wxGetApp().m_marked_list->list(); wxGetApp().m_marked_list->Clear(true); double angle; config.Read(_T("RotateAngle"), &angle, 90.0); // enter angle, plane and position double axis[3]; double pos[3]; config.Read(_T("RotateAxisX"), &axis[0], 0.0); config.Read(_T("RotateAxisY"), &axis[1], 0.0); config.Read(_T("RotateAxisZ"), &axis[2], 1.0); config.Read(_T("RotatePosX"), &pos[0], 0.0); config.Read(_T("RotatePosY"), &pos[1], 0.0); config.Read(_T("RotatePosZ"), &pos[2], 0.0); double axial_shift; config.Read(_T("RotateAxialShift"), &axial_shift, 0.0); if(!wxGetApp().InputAngleWithPlane(angle, axis, pos, copy ? &ncopies : NULL, &axial_shift))return; if(copy) { if(ncopies < 1)return; config.Write(_T("RotateNumCopies"), ncopies); } config.Write(_T("RotateAngle"), angle); config.Write(_T("RotateAxialShift"), axial_shift); config.Write(_T("RotateAxisX"), axis[0]); config.Write(_T("RotateAxisY"), axis[1]); config.Write(_T("RotateAxisZ"), axis[2]); config.Write(_T("RotatePosX"), pos[0]); config.Write(_T("RotatePosY"), pos[1]); config.Write(_T("RotatePosZ"), pos[2]); axis_Dir = gp_Dir(axis[0], axis[1], axis[2]); line_Pos = gp_Pnt(pos[0], pos[1], pos[2]); // transform the objects wxGetApp().CreateUndoPoint(); if(copy) { for(int i = 0; i<ncopies; i++) { gp_Trsf mat; mat.SetRotation(gp_Ax1(line_Pos, axis_Dir), angle * M_PI/180 * (i+1)); gp_Trsf tmat; tmat.SetTranslation(gp_Vec(axis_Dir.XYZ() * (axial_shift * ((double)(i+1)) / ncopies))); mat = tmat * mat; double m[16]; extract(mat, m); for(std::list<HeeksObj*>::iterator It = selected_items.begin(); It != selected_items.end(); It++) { HeeksObj* object = *It; HeeksObj* new_object = object->MakeACopy(); new_object->ModifyByMatrix(m); // Rotate the duplicate object. #ifdef MULTIPLE_OWNERS object->HEEKSOBJ_OWNER->Add(new_object, NULL); // And add it to this object's owner #else object->m_owner->Add(new_object, NULL); // And add it to this object's owner #endif } } wxGetApp().m_marked_list->Clear(true); } else { gp_Trsf mat; mat.SetRotation(gp_Ax1(line_Pos, axis_Dir), angle * M_PI/180); gp_Trsf tmat; tmat.SetTranslation(gp_Vec(axis_Dir.XYZ() * axial_shift)); mat = tmat * mat; double m[16]; extract(mat, m); wxGetApp().Transform(selected_items, m); } wxGetApp().Changed(); }