예제 #1
0
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);
}
예제 #2
0
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;
}