第二章:Pythonocc官方demo 案例44(几何板条)

news2025/8/12 18:31:38

源代码:

##Copyright 2009-2016 Jelle Feringa (jelleferinga@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/>.
from __future__ import print_function

import os
import sys
import time

from OCC.Core.BRep import BRep_Tool
from OCC.Core.BRepAdaptor import BRepAdaptor_HCurve
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakePolygon
from OCC.Core.BRepFill import BRepFill_CurveConstraint
from OCC.Display.SimpleGui import init_display
from OCC.Core.GeomAbs import GeomAbs_C0
from OCC.Core.GeomLProp import GeomLProp_SLProps
from OCC.Core.GeomPlate import (GeomPlate_BuildPlateSurface, GeomPlate_PointConstraint,
	                            GeomPlate_MakeApprox)
from OCC.Core.ShapeAnalysis import ShapeAnalysis_Surface
from OCC.Core.gp import gp_Pnt
from OCC.Core.BRepFill import BRepFill_Filling

from OCC.Extend.TopologyUtils import TopologyExplorer, WireExplorer
from OCC.Extend.ShapeFactory import make_face, make_vertex
from OCC.Extend.DataExchange import read_iges_file

display, start_display, add_menu, add_function_to_menu = init_display()

try:
    HAS_SCIPY = True
    from scipy.optimize import fsolve
except ImportError:
    print('scipy not installed, will not be able to run the geomplate example')
    HAS_SCIPY = False

# TODO:
# - need examples where the tangency to constraining faces is respected


def make_n_sided(edges, points, continuity=GeomAbs_C0):
    """
    builds an n-sided patch, respecting the constraints defined by *edges*
    and *points*

    a simplified call to the BRepFill_Filling class
    its simplified in the sense that to all constraining edges and points
    the same level of *continuity* will be applied

    *continuity* represents:

    GeomAbs_C0 : the surface has to pass by 3D representation of the edge
    GeomAbs_G1 : the surface has to pass by 3D representation of the edge
    and to respect tangency with the given face
    GeomAbs_G2 : the surface has to pass by 3D representation of the edge
    and to respect tangency and curvature with the given face.

    NOTE: it is not required to set constraining points.
    just leave the tuple or list empty

    :param edges: the constraining edges
    :param points: the constraining points
    :param continuity: GeomAbs_0, 1, 2
    :return: TopoDS_Face
    """
    n_sided = BRepFill_Filling()
    for edg in edges:
        n_sided.Add(edg, continuity)
    for pt in points:
        n_sided.Add(pt)
    n_sided.Build()
    face = n_sided.Face()
    return face


def make_closed_polygon(*args):
    poly = BRepBuilderAPI_MakePolygon()
    for pt in args:
        if isinstance(pt, list) or isinstance(pt, tuple):
            for i in pt:
                poly.Add(i)
        else:
            poly.Add(pt)
    poly.Build()
    poly.Close()
    result = poly.Wire()
    return result



def geom_plate(event=None):
    display.EraseAll()
    p1 = gp_Pnt(0, 0, 0)
    p2 = gp_Pnt(0, 10, 0)
    p3 = gp_Pnt(0, 10, 10)
    p4 = gp_Pnt(0, 0, 10)
    p5 = gp_Pnt(5, 5, 5)
    poly = make_closed_polygon([p1, p2, p3, p4])
    edges = [i for i in TopologyExplorer(poly).edges()]
    face = make_n_sided(edges, [p5])
    display.DisplayShape(edges)
    display.DisplayShape(make_vertex(p5))
    display.DisplayShape(face, update=True)


# ============================================================================
# Find a surface such that the radius at the vertex is n
# ============================================================================


def build_plate(polygon, points):
    '''
    build a surface from a constraining polygon(s) and point(s)
    @param polygon:     list of polygons ( TopoDS_Shape)
    @param points:      list of points ( gp_Pnt )
    '''
    # plate surface
    bpSrf = GeomPlate_BuildPlateSurface(3, 15, 2)

    # add curve constraints
    for poly in polygon:
        for edg in WireExplorer(poly).ordered_edges():
            c = BRepAdaptor_HCurve()
            c.ChangeCurve().Initialize(edg)
            constraint = BRepFill_CurveConstraint(c, 0)
            bpSrf.Add(constraint)

    # add point constraint
    for pt in points:
        bpSrf.Add(GeomPlate_PointConstraint(pt, 0))
        bpSrf.Perform()

    maxSeg, maxDeg, critOrder = 9, 8, 0
    tol = 1e-4
    dmax = max([tol, 10 * bpSrf.G0Error()])

    srf = bpSrf.Surface()
    plate = GeomPlate_MakeApprox(srf, tol, maxSeg, maxDeg, dmax, critOrder)
    uMin, uMax, vMin, vMax = srf.Bounds()

    return make_face(plate.Surface(), uMin, uMax, vMin, vMax, 1e-4)


def radius_at_uv(face, u, v):
    '''
    returns the mean radius at a u,v coordinate
    @param face:    surface input
    @param u,v:     u,v coordinate
    '''
    h_srf = BRep_Tool().Surface(face)
    #uv_domain = GeomLProp_SurfaceTool().Bounds(h_srf)
    curvature = GeomLProp_SLProps(h_srf, u, v, 1, 1e-6)
    try:
        _crv_min = 1. / curvature.MinCurvature()
    except ZeroDivisionError:
        _crv_min = 0.

    try:
        _crv_max = 1. / curvature.MaxCurvature()
    except ZeroDivisionError:
        _crv_max = 0.
    return abs((_crv_min + _crv_max) / 2.)


def uv_from_projected_point_on_face(face, pt):
    '''
    returns the uv coordinate from a projected point on a face
    '''
    srf = BRep_Tool().Surface(face)
    sas = ShapeAnalysis_Surface(srf)
    uv = sas.ValueOfUV(pt, 1e-2)
    print('distance ', sas.Value(uv).Distance(pt))
    return uv.Coord()


class RadiusConstrainedSurface():
    '''
    returns a surface that has `radius` at `pt`
    '''

    def __init__(self, display, poly, pnt, targetRadius):
        self.display = display
        self.targetRadius = targetRadius
        self.poly = poly
        self.pnt = pnt
        self.plate = self.build_surface()

    def build_surface(self):
        '''
        builds and renders the plate
        '''
        self.plate = build_plate([self.poly], [self.pnt])
        self.display.EraseAll()
        self.display.DisplayShape(self.plate)
        vert = make_vertex(self.pnt)
        self.display.DisplayShape(vert, update=True)

    def radius(self, z):
        '''
        sets the height of the point constraining the plate, returns
        the radius at this point
        '''
        if isinstance(z, float):
            self.pnt.SetX(z)
        else:
            self.pnt.SetX(float(z[0]))
        self.build_surface()
        uv = uv_from_projected_point_on_face(self.plate, self.pnt)
        radius = radius_at_uv(self.plate, uv[0], uv[1])
        print('z: ', z, 'radius: ', radius)
        self.curr_radius = radius
        return self.targetRadius - abs(radius)

    def solve(self):
        fsolve(self.radius, 1, maxfev=1000)
        return self.plate


def solve_radius(event=None):
    if not HAS_SCIPY:
        print("sorry cannot run solve_radius, scipy was not found...")
        return
    display.EraseAll()
    p1 = gp_Pnt(0, 0, 0)
    p2 = gp_Pnt(0, 10, 0)
    p3 = gp_Pnt(0, 10, 10)
    p4 = gp_Pnt(0, 0, 10)
    p5 = gp_Pnt(5, 5, 5)
    poly = make_closed_polygon([p1, p2, p3, p4])
    for i in (0.1, 0.5, 1.5, 2., 3., 0.2):
        rcs = RadiusConstrainedSurface(display, poly, p5, i)
        rcs.solve()
        print('Goal: %s radius: %s' % (i, rcs.curr_radius))
        time.sleep(0.1)


def build_geom_plate(edges):
    bpSrf = GeomPlate_BuildPlateSurface(3, 9, 12)

    # add curve constraints
    for edg in edges:
        c = BRepAdaptor_HCurve()
        print('edge:', edg)
        c.ChangeCurve().Initialize(edg)
        constraint = BRepFill_CurveConstraint(c, 0)
        bpSrf.Add(constraint)

    # add point constraint
    try:
        bpSrf.Perform()
    except RuntimeError:
        print('failed to build the geom plate surface ')

    srf = bpSrf.Surface()
    plate = GeomPlate_MakeApprox(srf, 0.01, 10, 5, 0.01, 0, GeomAbs_C0)

    uMin, uMax, vMin, vMax = srf.Bounds()
    face = make_face(plate.Surface(), uMin, uMax, vMin, vMax, 1e-6)
    return face


def build_curve_network(event=None):
    '''
    mimic the curve network surfacing command from rhino
    '''
    print('Importing IGES file...')
    iges_file = os.path.join('..', 'assets', 'models', 'curve_geom_plate.igs')
    iges = read_iges_file(iges_file)

    print('Building geomplate...')
    topo = TopologyExplorer(iges)
    edges_list = list(topo.edges())
    face = build_geom_plate(edges_list)
    print('done.')
    display.EraseAll()
    display.DisplayShape(edges_list)
    display.DisplayShape(face)
    display.FitAll()
    print('Cutting out of edges...')


def exit(event=None):
    sys.exit()


if __name__ == "__main__":
    add_menu('geom plate')
    add_function_to_menu('geom plate', geom_plate)
    add_function_to_menu('geom plate', solve_radius)
    add_function_to_menu('geom plate', build_curve_network)
    add_function_to_menu('geom plate', exit)

    build_curve_network()
    start_display()

运行效果:生成几何板条
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/33428.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库 Apache Doris 展开了为期两个月的调研测试

2022 年 3 月开始&#xff0c;我们对符合以上特点的数据库 Apache Doris 展开了为期两个月的调研测试。以下是 Apache Doris 1.1.2 在各个方面的满足情况。 基于上述情况&#xff0c;我们决定采用 Apache Doris&#xff0c;除了可以满足上文提到的几个特点&#xff0c;我们还考…

[信息系统项目管理师-2023备考]信息化与信息系统(一)

1.信息的质量特性 精确性&#xff1a;对事物状态描述的精准程度完整性&#xff1a;对事物状态描述的全面程度&#xff0c;完整信息应该包括所有重要事实可靠性&#xff1a;信息的来源、采集方法、传输过程是可以信任的&#xff0c;符合预期及时性&#xff1a;获取信息的时刻与…

(八)RabbitMQ发布确认

发布确认1、发布确认原理2、发布确认策略2.1、开启发布确认的方法2.2、单个确认发布2.3、批量确认发布2.4、异步确认发布2.5、处理异步未确认消息1、发布确认原理 书面文&#xff1a;生产者将信道设置成 confirm 模式&#xff0c;一旦信道进入 confirm 模式&#xff0c;所有在…

Python集合类型详解(一)——集合定义与集合操作符

今天继续给大家介绍Python相关知识&#xff0c;本文主要内容是Python集合类型定义与集合操作符。 一、集合类型定义 在Python中&#xff0c;集合是一种非常重要的组合数据类型。Python中的集合与数学中的集合非常相似&#xff0c;集合中的数据没有顺序&#xff0c;并且每个元…

第二章:Pythonocc官方demo 案例45(几何轴向曲线偏置)

源代码&#xff1a; #!/usr/bin/env python##Copyright 2009-2016 Jelle Feringa (jelleferingagmail.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 …

【优化调度】遗传算法求解工件的并行调度组合优化问题【含Matlab源码 2234期】

⛄ 一、 遗传算法简介 1 问题描述 假定一个加工系统有m台机器和n件工件&#xff0c;每个工件包含一道或多道工序,工件的加工顺序是确定的,但每个工件可能有几条可行的加工路线,即每道工序可在多台不同的机床上加工,工序的加工时间和加工费用随机床的性能不同而变化。作业调度的…

并查集解析

文章目录&#x1f6a9;并查集的理解&#x1f6a9;并查集的结构与原理&#x1f6a9;并查集的实现&#x1f341;整体框架&#x1f341;路径压缩&#x1f6a9;总结&#x1f6a9;并查集的理解 并查集是基于数组操作的一个特殊数据结构&#xff0c;和以前学习[数组的堆排序]时有点相…

分析设备树文件

1.设备树是干嘛的 硬件资源有很多&#xff0c;想要实现分类管理&#xff0c;方便驱动去控制它&#xff0c;则需要设备树来管理硬件信息。 所以&#xff0c;设备树主要存放了一些设备节点信息&#xff0c;键值对&#xff0c;和属性&#xff1b;节点中也可以包含子节点。 2.设…

安全架构中的前端安全防护研究

国家互联网应急中心发布的被篡改网站数据让很多人触目惊心&#xff0c;近年来各种Web网站攻击事件频频发生&#xff0c;网站SQL注入&#xff0c;网页被篡改、信息失窃、甚至被利用成传播木马的载体Web安全形势日益严峻&#xff0c;越来越受到人们的关注。 Gartner 对安全架构的…

创建计划协议、维护创建计划、收货

创建计划协议事务码&#xff1a;ME31L创建计划协议 &#xff08;ME32L 修改计划协议 ME33L查询计划协议 ME2L查询采购订单&#xff09; 输入&#xff1a;供应商、协议类型、协议日期、采购组织、采购组、工厂、存储地点等信息后回车。 然后输入有效截至日期&#xff0c; 再点击…

计算机毕业设计java+springboot宠物商城系统

一、项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot Maven mybatis Vue 等等组成&#xff0c;B…

【JVM】垃圾回收:垃圾收集器

一、语境中的并行与并发 并行 并行描述的时多条垃圾收集器线程之间的关系&#xff0c;说明同一时间有多条这样的线程在协同工作&#xff0c;通常默认此时用户线程是处于等待状态。 并发 并发描述的是垃圾收集器线程与用户线程之间的关系&#xff0c;说明同一时间垃圾收集器线程…

简单实现一个虚拟形象系统

前言 上周启动居家开会的时候&#xff0c;看到有人通过「虚拟形象」功能&#xff0c;给自己带上了口罩、眼镜之类&#xff0c;于是想到了是不是也可以搞一个简单的虚拟形象系统。 大致想来&#xff0c;分为以下几个部分&#xff1a; 卷积神经网络(CNN) 下面讲解一下三层CN…

视频格式转换器哪个好用?万兴优转-好用的视频格式转换器

视频格式转换器是用于转换视频格式的软件&#xff0c;是指用于视频转换、音频转换、CD轨抓取、音视频混合转换、音视频剪切、连接转换、视频水印叠加、滚动字幕、个性化文字、图片叠加、视频相框叠加的音视频转换工具。 也就是说&#xff0c;视频有非常多的格式如AVI、VCD、SVC…

【JavaWeb从零到一】会话技术CookieSessionJSP

&#x1f680;【JavaWeb从零到一】系列文章目录 &#x1f6a9;【JavaWeb从零到一】前置知识 &#x1f6a9;【JavaWeb从零到一】Mysql基础总结 &#x1f6a9;【JavaWeb从零到一】JDBC详解 &#x1f6a9;【JavaWeb从零到一】JDBC连接池&JDBCTemplate Cookie&Session&…

王学岗音视频开发(二)—————OpenGLES开发实践

矩阵以及矩阵运算 上图就是m x a 的矩阵 1x30x22x1 :为左侧第一行乘以右侧第一列。 1x10x12x0 :为左侧第一行乘以右侧第二列。 -1x33x21x1:为左侧第二行乘以右侧第一列。 -1x13x11x0:为左侧第二行乘以右侧第二列。 矩阵的行列式 伴随矩阵 A*表示伴随矩阵 OpenGL 教程----屏…

Grails SpringBoot国际化不生效

问题描述&#xff1a; grails项目使用了国际化&#xff0c;按照官方文档的说法&#xff1a; 会根据用户浏览器访问时使用的Accept-Language头自动选择合适的语言。 但无论浏览器了配置什么语言甚至配置了Tomcat启动参数 -Duser.languagexxx -Duser.regionxxx页面显示依旧是英…

[附源码]java毕业设计一点到家小区微帮服务系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

QPushButton按钮用法

QPushButton 简介 QPushButton是一个很常用的一个按钮控件&#xff0c;主要用于创建一个可按压的按键。它显示了一 个文本和一个图标。另外&#xff0c;你也可以在创建时&#xff0c;指定一个快捷键。 基本用法 1. 创建 QPushButton主要有两种创建方法&#xff0c;一种是直…

SQLite实现的学生管理系统

SQLite数据库 案例资源所在地址&#xff1a; https://download.csdn.net/download/weixin_41957626/87150608?spm1001.2014.3001.5503 1.简介 1.1引入 1.前面学习的文件存储和SharedPreference存储的方式只能存储一些小型的数据但是对于复杂关系以及复杂数据结构的数据仅仅靠…