FreeCAD的python脚本编写

简介

FreeCAD是一款强大的开源CAD软件,可以与python无缝对解,使用python来驱动三维几何的构建,具有很高的灵活性。本文主要讨论一下录制宏的方法,以及如何驱动特定参数

方法

打开FreeCAD软件,点击录制宏按钮后,建立如下简单的三维模型
在这里插入图片描述模型建好之后,结束宏录制,可以得到一段python代码
在这里插入图片描述阅读代码,不难理解何处对哪些尺寸进行了赋值。所以只需要将这些“尺寸数值”用python变量替代即可实现参数化驱动。

以下代码利用python的random库,将圆柱半径、长度、矩形孔宽度和高度设置为随机数,并把生成的几何保存为webGL格式

# -*- coding: utf-8 -*-

# Macro Begin: /home/liwentao/.local/share/FreeCAD/Macro/myRandomCoin.FCMacro +++++++++++++++++++++++++++++++++++++++++++++++++
import FreeCAD
import PartDesign
import PartDesignGui
import Sketcher
import random

R= random.uniform(20, 40)
L=random.uniform(50, 200)
DX=random.uniform(5, 15)
DY=random.uniform(5, 15)

### Begin command Std_Delete
if App.getDocument('Unnamed').getObject('Body') is not None:
	App.getDocument('Unnamed').getObject('Body').removeObjectsFromDocument()
	App.getDocument('Unnamed').removeObject('Body')
	App.getDocument('Unnamed').recompute()
### End command Std_Delete

### Begin command PartDesign_Body
App.activeDocument().addObject('PartDesign::Body','Body')
App.ActiveDocument.getObject('Body').Label = '实体'
App.ActiveDocument.recompute()
### End command PartDesign_Body
# Gui.Selection.addSelection('Unnamed','Body')
# Gui.Selection.clearSelection()
# Gui.Selection.addSelection('Unnamed','Body','Origin.XY_Plane.')
App.getDocument('Unnamed').getObject('Body').newObject('Sketcher::SketchObject','Sketch')
App.getDocument('Unnamed').getObject('Sketch').Support = (App.getDocument('Unnamed').getObject('XY_Plane'),[''])
App.getDocument('Unnamed').getObject('Sketch').MapMode = 'FlatFace'
App.ActiveDocument.recompute()
# Gui.Selection.clearSelection()
App.getDocument('Unnamed').getObject('Sketch').addGeometry(Part.Circle(App.Vector(0.0,0.000000,0),App.Vector(0,0,1),R),False)
App.getDocument('Unnamed').getObject('Sketch').addConstraint(Sketcher.Constraint('PointOnObject',0,3,-1)) 
App.ActiveDocument.recompute()
# Gui.Selection.addSelection('Unnamed','Body','Sketch.Edge1',19.808,16.0901,0)
App.getDocument('Unnamed').getObject('Sketch').addConstraint(Sketcher.Constraint('Diameter',0,R*2))
#App.getDocument('Unnamed').getObject('Sketch').setDatum(1,App.Units.Quantity('49.570000 mm'))
App.ActiveDocument.recompute()
App.ActiveDocument.recompute()
# Gui.Selection.clearSelection()
# Gui.Selection.addSelection('Unnamed','Body','Sketch.Vertex1',0.954255,0,0)
# Gui.Selection.addSelection('Unnamed','Body','Sketch.V_Axis',0,-0.04614,0)
App.getDocument('Unnamed').getObject('Sketch').addConstraint(Sketcher.Constraint('PointOnObject',0,3,-2))
App.ActiveDocument.recompute()
# Gui.Selection.clearSelection()
App.ActiveDocument.recompute()
# Gui.Selection.addSelection('Unnamed','Body','Sketch.')
App.getDocument('Unnamed').recompute()
### Begin command PartDesign_Pad
App.getDocument('Unnamed').getObject('Body').newObject('PartDesign::Pad','Pad')
App.getDocument('Unnamed').getObject('Pad').Profile = App.getDocument('Unnamed').getObject('Sketch')
App.getDocument('Unnamed').getObject('Pad').Length = L
App.ActiveDocument.recompute()
App.getDocument('Unnamed').getObject('Pad').ReferenceAxis = (App.getDocument('Unnamed').getObject('Sketch'),['N_Axis'])
App.getDocument('Unnamed').getObject('Sketch').Visibility = False
App.ActiveDocument.recompute()
### End command PartDesign_Pad
# Gui.Selection.clearSelection()
App.getDocument('Unnamed').getObject('Pad').TaperAngle = 0.000000
App.getDocument('Unnamed').getObject('Pad').UseCustomVector = 0
App.getDocument('Unnamed').getObject('Pad').Direction = (0, 0, 1)
App.getDocument('Unnamed').getObject('Pad').ReferenceAxis = (App.getDocument('Unnamed').getObject('Sketch'), ['N_Axis'])
App.getDocument('Unnamed').getObject('Pad').AlongSketchNormal = 1
App.getDocument('Unnamed').getObject('Pad').Type = 0
App.getDocument('Unnamed').getObject('Pad').UpToFace = None
App.getDocument('Unnamed').getObject('Pad').Reversed = 0
App.getDocument('Unnamed').getObject('Pad').Midplane = 0
App.getDocument('Unnamed').getObject('Pad').Offset = 0
App.getDocument('Unnamed').recompute()
App.getDocument('Unnamed').getObject('Sketch').Visibility = False
# Gui.Selection.addSelection('Unnamed','Body')
# Gui.Selection.clearSelection()
# Gui.Selection.addSelection('Unnamed','Body','Origin.XY_Plane.',-18.5177,-32.2205,0)
App.getDocument('Unnamed').getObject('Body').newObject('Sketcher::SketchObject','Sketch001')
App.getDocument('Unnamed').getObject('Sketch001').Support = (App.getDocument('Unnamed').getObject('XY_Plane'),[''])
App.getDocument('Unnamed').getObject('Sketch001').MapMode = 'FlatFace'
App.ActiveDocument.recompute()
# Gui.Selection.clearSelection()
### Begin command Sketcher_ViewSketch
### End command Sketcher_ViewSketch
### Begin command Sketcher_ViewSection
#ActiveSketch.ViewObject.TempoVis.sketchClipPlane(ActiveSketch, None, False)

### End command Sketcher_ViewSection
App.getDocument('Unnamed').getObject('Sketch001').addConstraint(Sketcher.Constraint('Coincident',4,1,-1,1)) 
App.ActiveDocument.recompute()
# Gui.Selection.addSelection('Unnamed','Body','Sketch001.Edge4',2.50686,-10.9,0)
App.getDocument('Unnamed').getObject('Sketch001').addConstraint(Sketcher.Constraint('DistanceX',3,2,3,1,DX))
#App.getDocument('Unnamed').getObject('Sketch001').setDatum(10,App.Units.Quantity('21.870000 mm'))
App.ActiveDocument.recompute()
App.ActiveDocument.recompute()
# Gui.Selection.clearSelection()
# Gui.Selection.addSelection('Unnamed','Body','Sketch001.Edge3',10.935,6.8364,0)
App.getDocument('Unnamed').getObject('Sketch001').addConstraint(Sketcher.Constraint('DistanceY',2,2,2,1,DY))
#App.getDocument('Unnamed').getObject('Sketch001').setDatum(11,App.Units.Quantity('21.800000 mm'))
App.ActiveDocument.recompute()
App.ActiveDocument.recompute()
# Gui.Selection.clearSelection()
App.ActiveDocument.recompute()
# Gui.Selection.addSelection('Unnamed','Body','Sketch001.')
App.getDocument('Unnamed').recompute()
### Begin command PartDesign_Pocket
App.getDocument('Unnamed').getObject('Body').newObject('PartDesign::Pocket','Pocket')
App.getDocument('Unnamed').getObject('Pocket').Profile = App.getDocument('Unnamed').getObject('Sketch001')
App.getDocument('Unnamed').getObject('Pocket').Length = 5
App.ActiveDocument.recompute()
App.getDocument('Unnamed').getObject('Pocket').ReferenceAxis = (App.getDocument('Unnamed').getObject('Sketch001'),['N_Axis'])
App.getDocument('Unnamed').getObject('Sketch001').Visibility = False
App.ActiveDocument.recompute()
### End command PartDesign_Pocket
# Gui.Selection.clearSelection()
App.getDocument('Unnamed').getObject('Pocket').UseCustomVector = 0
App.getDocument('Unnamed').getObject('Pocket').Direction = (0, 0, -1)
App.getDocument('Unnamed').getObject('Pocket').ReferenceAxis = (App.getDocument('Unnamed').getObject('Sketch001'), ['N_Axis'])
App.getDocument('Unnamed').getObject('Pocket').AlongSketchNormal = 1
App.getDocument('Unnamed').getObject('Pocket').Type = 1
App.getDocument('Unnamed').getObject('Pocket').UpToFace = None
App.getDocument('Unnamed').getObject('Pocket').Reversed = 1
App.getDocument('Unnamed').getObject('Pocket').Midplane = 0
App.getDocument('Unnamed').getObject('Pocket').Offset = 0
App.getDocument('Unnamed').recompute()
App.getDocument('Unnamed').getObject('Pad').Visibility = False
App.getDocument('Unnamed').getObject('Sketch001').Visibility = False

### Begin command Std_Export
__objs__ = []
__objs__.append(FreeCAD.getDocument("Unnamed").getObject("Body"))
import importWebGL
if hasattr(importWebGL, "exportOptions"):
    options = importWebGL.exportOptions(u"/home/liwentao/demo/freeCAD/RandomCoin.html")
    importWebGL.export(__objs__, u"/home/liwentao/demo/freeCAD/RandomCoin.html", options)
else:
    importWebGL.export(__objs__, u"/home/liwentao/demo/freeCAD/RandomCoin.html")
del __objs__
### End command Std_Export
# Macro End: /home/liwentao/.local/share/FreeCAD/Macro/myRandomCoin.FCMacro +++++++++++++++++++++++++++++++++++++++++++++++++

保存得到的webGL格式文件可用浏览器打开

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++实现鼠标点击和获取鼠标位置(编译环境visual studio 2022)

1环境说明 2获取鼠标位置的接口 void GetMouseCurPoint() {POINT mypoint;for (int i 0; i < 100; i){GetCursorPos(&mypoint);//获取鼠标当前所在位置printf("% ld, % ld \n", mypoint.x, mypoint.y);Sleep(1000);} } 3操作鼠标左键和右键的接口 void Mo…

什么是功能安全?

前言 在上一家公司的时候&#xff0c;有幸参加过公司内部的技术分享会&#xff0c;有一个同事跟我们分享了功能安全的一些内容。在提问环节&#xff0c;我问了一个问题“什么是功能安全&#xff1f;”他回答不上来。这也是我们很多人在工作中常犯的一个问题&#xff1a;我们做了…

汽车租赁系统

目录 一.研究背景 二.系统架构 1、SSM 2、JAVA 3、MySQL 4、系统架构 三.系统功能 1、车辆管理 2、客户管理 3、销售管理 4、统计分析 四.系统实现 五.结论总结 一.研究背景 传统的销售与信息统计管理都主要依靠人工&#xff0c;处理出的销售数据量与使用管理系统…

vcruntime140.dll有什么作用?vcruntime140.dll缺失的解决方法分享

解决因缺少vcruntime140.dll文件引起的问题实际上是相对简单的尽管最近有许多人在抱怨该文件频繁丢失且不知道该如何处理。作为一个责任编辑&#xff0c;我认为有很大的必要向大家清楚地解释一下。让我们从探索vcruntime140.dll文件缺少的修复方法吧。 一.msvcp140.dll的作用 …

基于springboot就业信息管理系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;就业信息管理系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;市场规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而…

2024年美赛数学建模E题思路分析 - 财产保险的可持续性

# 1 赛题 问题E&#xff1a;财产保险的可持续性 极端天气事件正成为财产所有者和保险公司面临的危机。“近年来&#xff0c;世界已经遭受了1000多起极端天气事件造成的超过1万亿美元的损失”。[1]2022年&#xff0c;保险业的自然灾害索赔人数“比30年的平均水平增加了115%”。…

FastCAE合作开发项目:可执行调试的脚本编辑器

开发内容 1. 要求能够编辑脚本内容 2. 要求能够高亮显示关键字、纯数字、单行注释、多行注释等 3. 要求能够设置断点功能 4. 要求能够进行运行求解器、单步运行、暂停、继续、终止等基本调试功能 5. 要求能够高亮执行脚本&#xff0c;分别展示单脚本行执行中与执行完成效果…

更新npm镜像源:淘宝镜像已过期,及时切换!

你好&#xff0c;我是小白Coding日志&#xff0c;一个热爱技术的程序员。在这里&#xff0c;我分享自己在编程和技术世界中的学习心得和体会。希望我的文章能够给你带来一些灵感和帮助。欢迎来到我的博客&#xff0c;一起在技术的世界里探索前行吧&#xff01; 前言 就在昨天…

第二卷《皈依的意义与方法》

甲二、别明皈依的方法 分二&#xff1a;初、事相皈依。二、理体皈依。 前面一科讲到“皈依的意义”——“能皈依的心”跟“所皈依的境”。 “能皈依的心”就是我们有一种祈求救护的心情&#xff1b;“所皈依的境”有二种&#xff1a;一种是“住持三宝”&#xff0c;或者讲外…

Git快速入门+常用指令+提交规范

目录 Git创建本地仓库 IDEA集成Git Git和IDEA连接使用2 忽略文件 本地仓库常用命令 远程仓库常用命令 分支常用命令 标签操作 提交规范 Git创建本地仓库 1、创建一个文件夹&#xff0c;右键选择Git Bash Here 2、选择下列其中一个方法 方法一&#xff1a;创建初始化…

【算法与数据结构】583、72、LeetCode两个字符串的删除操作+编辑距离

文章目录 一、583、两个字符串的删除操作二、72、编辑距离三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、583、两个字符串的删除操作 思路分析&#xff1a;本题的思路和115、不同的子序列差不多&#xff0c;只是变成…

vue3+threejs+koa可视化项目——模型文件上传(第四步)

文章目录 ⭐前言&#x1f496;往期node系列文章&#x1f496;threejs系列相关文章&#x1f496;vue3threejs系列 ⭐koa后端文件上传(koa-body)&#x1f496;自动创建目录&#x1f496;自定义目录上传&#x1f496;apifox自测上传接口 ⭐vue3前端上传模型文件&#x1f496; axio…

【测试运维】性能测试笔记文档第2篇:性能测试分类和指标(已分享,附代码)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论性能测试相关知识。入门阶段&#xff1a;认识性能测试分类-(负载测试、压力测试、并发测试、稳定性测试)&#xff0c;常用性能测试指标-(吞吐量、并发数、响应时间、点击数…)&#xff0c;性能测试工具选择。性能脚本&a…

口味多样的碱水贝果面包,香气饱满松松软软

这两天在吃一款碱趣贝果面包&#xff0c;感觉味道很不错&#xff0c;它是一种加热一下就可以吃的手工面包&#xff0c;口感十分独特。这款面包有着清香有韧性的表皮&#xff0c;里面松软可口&#xff0c;加热后更是香气四溢。 除了标准的原味全麦之外&#xff0c;碱趣贝果面包还…

提取人声消除背景音乐的工具?分享4款!

音乐是生活中不可或缺的调味品&#xff0c;我们常常会遇到一些音乐中的对话或人声干扰了我们的聆听体验。那么&#xff0c;有没有一种方法可以消除这些干扰&#xff0c;只留下纯净的背景音乐呢&#xff1f;答案是肯定的&#xff0c;下面为大家介绍4款能够消除人声保留背景音乐的…

LNMP.

一.mysl配置 1.安装mysql yum install mysql-server -y 2.进入mysql配置文件目录 cd /etc/my.cnf.d3.编辑mysql配置文件 vim mysql-server.cnf 在[mysqld]中添加: character-set-serverutf84.启动mysql服务 systemctl start mysqld5.登入mysql mysql 6.创建数据库 cre…

泡泡清新文艺的微社区系统PHP源码

泡泡微社区&#xff0c;小巧而强大&#xff0c;为您带来卓越的社区交流体验。 凭借GoZinc的先进架构&#xff0c;泡泡在保持轻盈身姿的同时&#xff0c;功能一应俱全。前端采用Vue3匠心打造&#xff0c;界面清新简约&#xff0c;三栏式布局仿若Twitter&#xff0c;让您一见倾心…

PyTorch 2.2 中文官方教程(十五)

&#xff08;beta&#xff09;计算机视觉的量化迁移学习教程 原文&#xff1a;pytorch.org/tutorials/intermediate/quantized_transfer_learning_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 提示 为了充分利用本教程&#xff0c;我们建议使用这个C…

Vue3页面自适应,表格滚动高度

适用场景&#xff1a;在网页表格中我们需要获取页面剩余高度来为表格做滚动的时候就需要使用响应高度&#xff0c;可以使用原生calc来计算&#xff0c;但是calc有个缺陷就是&#xff0c;有可能要去计算多个盒子高度&#xff0c;使用下面的代码就可以直接获取当前元素到顶部的距…

考研中常见的算法-逆置

元素逆置 概述&#xff1a;其实就是将 第一个元素和最后一个元素交换&#xff0c;第二个元素和倒数第二个元素交换&#xff0c;依次到中间位置。用途&#xff1a;可用于数组的移动&#xff0c;字符串反转&#xff0c;链表反转操作&#xff0c;栈和队列反转等操作。 逆置图解 …