zoukankan      html  css  js  c++  java
  • pythonOCC版 瓶子代码

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    ##Copyright 2009-2015 Thomas Paviot (tpaviot@gmail.com)
    ##
    ##This file is part of pythonOCC.
    ##
    ##pythonOCC is free software: you can redistribute it and/or modify
    ##it under the terms of the GNU Lesser General Public License as published by
    ##the Free Software Foundation, either version 3 of the License, or
    ##(at your option) any later version.
    ##
    ##pythonOCC is distributed in the hope that it will be useful,
    ##but WITHOUT ANY WARRANTY; without even the implied warranty of
    ##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ##GNU Lesser General Public License for more details.
    ##
    ##You should have received a copy of the GNU Lesser General Public License
    ##along with pythonOCC.  If not, see <http://www.gnu.org/licenses/>.
    
    import math
    
    from OCC.gp import gp_Pnt, gp_OX, gp_Vec, gp_Trsf, gp_DZ, gp_Ax2, gp_Ax3, gp_Pnt2d, gp_Dir2d, gp_Ax2d
    from OCC.GC import GC_MakeArcOfCircle, GC_MakeSegment
    from OCC.GCE2d import GCE2d_MakeSegment
    from OCC.Geom import Geom_Plane, Geom_CylindricalSurface, Handle_Geom_Plane, Handle_Geom_Surface
    from OCC.Geom2d import Geom2d_Ellipse, Geom2d_TrimmedCurve, Handle_Geom2d_Ellipse, Handle_Geom2d_Curve
    from OCC.BRepBuilderAPI import BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeWire, BRepBuilderAPI_MakeFace, 
        BRepBuilderAPI_Transform
    from OCC.BRepPrimAPI import BRepPrimAPI_MakePrism, BRepPrimAPI_MakeCylinder
    from OCC.BRepFilletAPI import BRepFilletAPI_MakeFillet
    from OCC.BRepAlgoAPI import BRepAlgoAPI_Fuse
    from OCC.BRepOffsetAPI import BRepOffsetAPI_MakeThickSolid, BRepOffsetAPI_ThruSections
    from OCC.BRepLib import breplib
    from OCC.BRep import BRep_Tool_Surface, BRep_Builder
    from OCC.TopoDS import topods, TopoDS_Edge, TopoDS_Compound
    from OCC.TopExp import TopExp_Explorer
    from OCC.TopAbs import TopAbs_EDGE, TopAbs_FACE
    from OCC.TopTools import TopTools_ListOfShape
    from OCC.Display.SimpleGui import *
    
    
    def face_is_plane(face):
        """
        判断 TopoDS_Shape 是不是 plane
        """
        hs = BRep_Tool_Surface(face)
        downcast_result = Handle_Geom_Plane.DownCast(hs)
        # 不能通过Handle_Geom_Plane转换的不是平面
        return not downcast_result.IsNull()
    
    
    def geom_plane_from_face(aFace):
        """
        通过  planar surface 得到 geometric plane 
        """
        return Handle_Geom_Plane.DownCast(BRep_Tool_Surface(aFace)).GetObject()
    
    
    height = 70
    width = 50
    thickness = 30
    
    if 1:
        # 准备用来创建 瓶身 的点
        aPnt1 = gp_Pnt(-width / 2.0, 0, 0)
        aPnt2 = gp_Pnt(-width / 2.0, -thickness / 4.0, 0)
        aPnt3 = gp_Pnt(0, -thickness / 2.0, 0)
        aPnt4 = gp_Pnt(width / 2.0, -thickness / 4.0, 0)
        aPnt5 = gp_Pnt(width / 2.0, 0, 0)
        
        # 瓶底断面线段和圆弧
        aArcOfCircle = GC_MakeArcOfCircle(aPnt2, aPnt3, aPnt4)
        aSegment1 = GC_MakeSegment(aPnt1, aPnt2)
        aSegment2 = GC_MakeSegment(aPnt4, aPnt5)
        
        # 除了下面的方法, 也可以不用上面的segment,而通过点直接创建线段edges
        aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1.Value())
        aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle.Value())
        aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2.Value())
        
        # 通过edges 创建 wire
        aWire = BRepBuilderAPI_MakeWire(aEdge1.Edge(), aEdge2.Edge(), aEdge3.Edge())
        
        # 得到X轴的便捷方式
        xAxis = gp_OX()
        
        # 设置镜像轴
        aTrsf = gp_Trsf()
        aTrsf.SetMirror(xAxis)
        
        # 应用镜像变换
        aBRespTrsf = BRepBuilderAPI_Transform(aWire.Wire(), aTrsf)
        
        # 得到镜像 shape
        aMirroredShape = aBRespTrsf.Shape()
        
        # 通过通用shape得到 wire
        aMirroredWire = topods.Wire(aMirroredShape)
        
        # 组合两个wire
        mkWire = BRepBuilderAPI_MakeWire()
        mkWire.Add(aWire.Wire())
        mkWire.Add(aMirroredWire)
        myWireProfile = mkWire.Wire()
        
        # 创建用于体拉伸 sweep 的面
        myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile)
        
        # 我们把面沿Z轴拉伸到指定高度
        aPrismVec = gp_Vec(0, 0, height)
        myBody = BRepPrimAPI_MakePrism(myFaceProfile.Face(), aPrismVec)
        
        # 通过explorer对所有边加倒角
        mkFillet = BRepFilletAPI_MakeFillet(myBody.Shape())
        anEdgeExplorer = TopExp_Explorer(myBody.Shape(), TopAbs_EDGE)
        
        while anEdgeExplorer.More():
            anEdge = topods.Edge(anEdgeExplorer.Current())
            mkFillet.Add(thickness / 12.0, anEdge)
        
            anEdgeExplorer.Next()
        
        myBody = mkFillet
    
    # 创建瓶颈
    neckLocation = gp_Pnt(0, 0, height)
    neckAxis = gp_DZ()
    neckAx2 = gp_Ax2(neckLocation, neckAxis)
    
    myNeckRadius = thickness / 4.0
    myNeckHeight = height / 10.0
    
    mkCylinder = BRepPrimAPI_MakeCylinder(neckAx2, myNeckRadius, myNeckHeight)
    
    myBody = BRepAlgoAPI_Fuse(myBody.Shape(), mkCylinder.Shape())
    
    # 下面找到Z最高的面, 并将它移除
    faceToRemove = None
    zMax = -1
    
    # 遍历所有的面, 查找Z最高的面
    aFaceExplorer = TopExp_Explorer(myBody.Shape(), TopAbs_FACE)
    while aFaceExplorer.More():
        aFace = topods.Face(aFaceExplorer.Current())
    
        if face_is_plane(aFace):
            aPlane = geom_plane_from_face(aFace)
    
            aPnt = aPlane.Location()
            aZ = aPnt.Z()
            if aZ > zMax:
                zMax = aZ
                faceToRemove = aFace
    
        aFaceExplorer.Next()
    
    facesToRemove = TopTools_ListOfShape()
    facesToRemove.Append(faceToRemove)
    
    myBody = BRepOffsetAPI_MakeThickSolid(myBody.Shape(), facesToRemove, -thickness / 50.0, 0.001)
    
    
    # 建立需要创建螺纹的瓶颈表面
    neckAx2_Ax3 = gp_Ax3(neckLocation, gp_DZ())
    aCyl1 = Geom_CylindricalSurface(neckAx2_Ax3, myNeckRadius * 0.99)
    aCyl2 = Geom_CylindricalSurface(neckAx2_Ax3, myNeckRadius * 1.05)
    
    # 建立创建螺纹的曲线
    aPnt = gp_Pnt2d(2.0 * math.pi, myNeckHeight / 2.0)
    aDir = gp_Dir2d(2.0 * math.pi, myNeckHeight / 4.0)
    anAx2d = gp_Ax2d(aPnt, aDir)
    
    aMajor = 2.0 * math.pi
    aMinor = myNeckHeight / 5.0
    
    anEllipse1 = Geom2d_Ellipse(anAx2d, aMajor, aMinor)
    anEllipse2 = Geom2d_Ellipse(anAx2d, aMajor, aMinor / 8.0)
    
    anArc1 = Geom2d_TrimmedCurve(Handle_Geom2d_Ellipse(anEllipse1), 0, math.pi)
    anArc2 = Geom2d_TrimmedCurve(Handle_Geom2d_Ellipse(anEllipse2), 0, math.pi)
    
    anEllipsePnt1 = anEllipse1.Value(0)
    anEllipsePnt2 = anEllipse1.Value(math.pi)
    
    aSegment = GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2)
    
    # 构建用于螺纹的边和环
    anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(Handle_Geom2d_Curve(anArc1), Handle_Geom_Surface(aCyl1))
    anEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment.Value(), Handle_Geom_Surface(aCyl1))
    anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(Handle_Geom2d_Curve(anArc2), Handle_Geom_Surface(aCyl2))
    anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment.Value(), Handle_Geom_Surface(aCyl2))
    
    threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1.Edge(), anEdge2OnSurf1.Edge())
    threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2.Edge(), anEdge2OnSurf2.Edge())
    
    # 计算边和环的三维表现
    breplib.BuildCurves3d(threadingWire1.Shape())
    breplib.BuildCurves3d(threadingWire2.Shape())
    
    # 创建螺纹的表面
    aTool = BRepOffsetAPI_ThruSections(True)
    aTool.AddWire(threadingWire1.Wire())
    aTool.AddWire(threadingWire2.Wire())
    aTool.CheckCompatibility(False)
    myThreading = aTool.Shape()
    
    # 构建组合结果
    aRes = TopoDS_Compound()
    aBuilder = BRep_Builder()
    aBuilder.MakeCompound(aRes)
    aBuilder.Add(aRes, myBody.Shape())
    aBuilder.Add(aRes, myThreading)
    
    display, start_display, add_menu, add_function_to_menu = init_display()
    display.DisplayColoredShape(aRes)
    
    start_display()
  • 相关阅读:
    各种排序(二)
    各种排序(一)
    【游记】CSP-S2019游记
    【题解】hdu1506 Largest Rectangle in a Histogram
    【题解】CF161B Discounts
    【CSP-S膜你考】我们的可可西里
    Bzoj3675 [Apio2014]序列分割
    Bzoj3853 GCD Array
    Bzoj3876 [Ahoi2014]支线剧情
    Bzoj2324 [ZJOI2011]营救皮卡丘
  • 原文地址:https://www.cnblogs.com/yaoyu126/p/6910234.html
Copyright © 2011-2022 走看看