void occQt::makeCylinder() { gp_Ax2 anAxis; anAxis.SetLocation(gp_Pnt(0.0, 30.0, 0.0)); TopoDS_Shape aTopoCylinder = BRepPrimAPI_MakeCylinder(anAxis, 3.0, 5.0); Handle_AIS_Shape anAisCylinder = new AIS_Shape(aTopoCylinder); anAisCylinder->SetColor(Quantity_NOC_RED); anAxis.SetLocation(gp_Pnt(8.0, 30.0, 0.0)); TopoDS_Shape aTopoPie = BRepPrimAPI_MakeCylinder(anAxis, 3.0, 5.0, M_PI_2 * 3.0); Handle_AIS_Shape anAisPie = new AIS_Shape(aTopoPie); anAisPie->SetColor(Quantity_NOC_TAN); mContext->Display(anAisCylinder); mContext->Display(anAisPie); }
static TopoDS_Solid MakeCylinder(const gp_Ax2& pos, double radius, double height) { gp_Ax2 pos2 = pos; if(height<0) { pos2 = gp_Ax2(pos.Location(), -(pos.Direction())); height = fabs(height); } return BRepPrimAPI_MakeCylinder(pos2, radius, height); }
// add a pad hole or slot bool PCBMODEL::AddPadHole( KICADPAD* aPad ) { if( NULL == aPad || !aPad->IsThruHole() ) return false; if( !aPad->m_drill.oval ) { TopoDS_Shape s = BRepPrimAPI_MakeCylinder( aPad->m_drill.size.x * 0.5, m_thickness * 2.0 ).Shape(); gp_Trsf shift; shift.SetTranslation( gp_Vec( aPad->m_position.x, aPad->m_position.y, -m_thickness * 0.5 ) ); BRepBuilderAPI_Transform hole( s, shift ); m_cutouts.push_back( hole.Shape() ); return true; } // slotted hole double angle_offset = 0.0; double rad; // radius of the slot double hlen; // half length of the slot if( aPad->m_drill.size.x < aPad->m_drill.size.y ) { angle_offset = M_PI_2; rad = aPad->m_drill.size.x * 0.5; hlen = aPad->m_drill.size.y * 0.5 - rad; } else { rad = aPad->m_drill.size.y * 0.5; hlen = aPad->m_drill.size.x * 0.5 - rad; } DOUBLET c0( -hlen, 0.0 ); DOUBLET c1( hlen, 0.0 ); DOUBLET p0( -hlen, rad ); DOUBLET p1( -hlen, -rad ); DOUBLET p2( hlen, -rad ); DOUBLET p3( hlen, rad ); angle_offset += aPad->m_rotation; double dlim = (double)std::numeric_limits< float >::epsilon(); if( angle_offset < -dlim || angle_offset > dlim ) { double vsin = sin( angle_offset ); double vcos = cos( angle_offset ); double x = c0.x * vcos - c0.y * vsin; double y = c0.x * vsin + c0.y * vcos; c0.x = x; c0.y = y; x = c1.x * vcos - c1.y * vsin; y = c1.x * vsin + c1.y * vcos; c1.x = x; c1.y = y; x = p0.x * vcos - p0.y * vsin; y = p0.x * vsin + p0.y * vcos; p0.x = x; p0.y = y; x = p1.x * vcos - p1.y * vsin; y = p1.x * vsin + p1.y * vcos; p1.x = x; p1.y = y; x = p2.x * vcos - p2.y * vsin; y = p2.x * vsin + p2.y * vcos; p2.x = x; p2.y = y; x = p3.x * vcos - p3.y * vsin; y = p3.x * vsin + p3.y * vcos; p3.x = x; p3.y = y; } c0.x += aPad->m_position.x; c0.y += aPad->m_position.y; c1.x += aPad->m_position.x; c1.y += aPad->m_position.y; p0.x += aPad->m_position.x; p0.y += aPad->m_position.y; p1.x += aPad->m_position.x; p1.y += aPad->m_position.y; p2.x += aPad->m_position.x; p2.y += aPad->m_position.y; p3.x += aPad->m_position.x; p3.y += aPad->m_position.y; OUTLINE oln; KICADCURVE crv0, crv1, crv2, crv3; // crv0 = arc crv0.m_start = c0; crv0.m_end = p0; crv0.m_ep = p1; crv0.m_angle = M_PI; crv0.m_radius = rad; crv0.m_form = CURVE_ARC; // crv1 = line crv1.m_start = p1; crv1.m_end = p2; crv1.m_form = CURVE_LINE; // crv2 = arc crv2.m_start = c1; crv2.m_end = p2; crv2.m_ep = p3; crv2.m_angle = M_PI; crv2.m_radius = rad; crv2.m_form = CURVE_ARC; // crv3 = line crv3.m_start = p3; crv3.m_end = p0; crv3.m_form = CURVE_LINE; oln.AddSegment( crv0 ); oln.AddSegment( crv1 ); oln.AddSegment( crv2 ); oln.AddSegment( crv3 ); TopoDS_Shape slot; if( oln.MakeShape( slot, m_thickness ) ) { if( !slot.IsNull() ) m_cutouts.push_back( slot ); return true; } return false; }
TopoShape DuplicateCylinderFilletBug(){ TopoDS_Shape Box = BRepPrimAPI_MakeBox(10., 10., 10.); TopoDS_Shape Cylinder = BRepPrimAPI_MakeCylinder(2., 10.); // in FreeCAD, every operation first creates a blank TopoShape and then adds the // TopoDS_Shape to it TopoShape BoxShape, CylShape, FusedShape; // The current FreeCAD source will directly set TopoShape._Shape from all kinds of // places in the code. I have added a TopoShape::setShape method so that we can have // some control over this. Note that this method is overloaded a few times BoxShape.setShape(Box, "Primitive Box"); CylShape.setShape(Cylinder, "Primitive Cylinder"); // As of now, I don't see the TopoShape fuse being used. rather, the fuse is done // outside and then stored to the TopoShape BRepAlgoAPI_Fuse mkFuse(Box, Cylinder); // in my current implementation, I send the FIRST TopoShape from the Fuse operation to // the setShape, and copy it's _TopoNamer FusedShape.setShape(BoxShape, mkFuse); // Now let's select an edge, then fillet it TopoDS_Shape BaseShape = mkFuse.Shape(); // Finaly, 'Select' the edge std::string selectionLabel = FusedShape.selectEdge(3); std::cout << "Selected Edge Node = " << selectionLabel << std::endl; // Write out the current-state of things //FusedShape.OCCDeepDump(); FusedShape.WriteTNamingNode("0:1:1", "01_Selected", true); FusedShape.WriteTNamingNode("0:2", "02_BaseBox", false); FusedShape.WriteTNamingNode("0:3", "03_BaseCyl", false); FusedShape.WriteTNamingNode("0:4", "04_FusedShape", false); // Fillet the selected edge TopoDS_Edge RecoveredEdge = FusedShape.getSelectedEdge(selectionLabel); BRepFilletAPI_MakeFillet mkFillet(FusedShape.getShape()); mkFillet.Add(2., 2., RecoveredEdge); mkFillet.Build(); // Record the Fillet Operation TopoShape FilletedShape;// = mkFillet.Shape(); FilletedShape.setShape(FusedShape, mkFillet); // write out the latest node FusedShape.WriteTNamingNode("0:5", "05_FilletedShape", false); //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- // FUSE DONE, ABOUT TO RESIZE THE CYLINDER //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- // resize the cylinder. I believe FreeCAD just creates a whole new cylinder TopoDS_Shape Cylinder2 = BRepPrimAPI_MakeCylinder(2., 15.); TopoShape NewCylShape; NewCylShape.setShape(Cylinder2); // Now the FreeCAD algorithms figure out that Fuse and Fillet need to be re-run // First, re-do Fuse TopoShape ReFusedShape; BRepAlgoAPI_Fuse mkFuse2(BoxShape.getShape(), NewCylShape.getShape()); ReFusedShape.setShape(BoxShape, mkFuse2); BRepFilletAPI_MakeFillet mkFillet2(ReFusedShape.getShape()); // grab the selected edge from our tree to re-fillet TopoDS_Edge RecoveredEdge2 = ReFusedShape.getSelectedEdge(selectionLabel); // now re-do fillet mkFillet2.Add(2., 2., RecoveredEdge); mkFillet2.Build(); // Record the Fillet Operation TopoShape ReFilletedShape;// = mkFillet2.Shape(); ReFilletedShape.setShape(ReFusedShape, mkFillet2); // Write out some more shapes FusedShape.WriteTNamingNode("0:6", "06_PartOfFusionMaybe", false); FusedShape.WriteTNamingNode("0:7", "07_ReFusion", false); FusedShape.WriteTNamingNode("0:8", "08_ReFillet", false); return FusedShape; }