讨论与说明:
参数化模型有多种实现方式,如SW,CATIA,MS,invent,FC等,但要实现服务化,
首先得支持外程序调用它这个软件接口,打开模型,解析出参数来,再将参数映射到网页或其他软件的插件上,用户修改参数,再驱动调用的接口来修改模型。常用的比如我们用VB程序调用ACAD的接口来处理dwg文件。
其次,服务器上是否需装这个软件?SW,CATIA,MS,invent,FC。比如我在服务器上用网络编程语言go来调用wps打开excel表格,服务器上就得安装wps才行,如果服务器是linux系统呢?所以服务器上需要装软件来解析模型是个麻烦。而FC不用。直接用我写的几行Python编译为exe文件 点这里,放服务器上。再用go调用即可解析FC模型,并用参数修改模型 点这里。
所以目前FC这个路线是走通的,才值得花力气生产参数化模型。FC还有个强大的FreecadCmd,任意的python代码或FC宏文件,都可以用freecadcmd来运行,即我们在界面上操作,记录下来的python代码,都可以在这个freecadcmd里运行,没有障碍。
而SW,CATIA,MS,invent等需软件开发人员验证后才知道能否走“服务”这个路线。
第三就是服务并发能力,即ch会上说的,同时100个人来改同一个模型,能同时调用接口修改模型吗?之前我调用mathcad参数化计算书,mathcad就没办法一个计算书同时被100个人修改,也没办法同时运算100个计算书,大家得排队 点这里。所以参数化到服务化至少得考虑这几点。
针对第三点,测试代码如下:
无并发情况下,串行执行,将一个模型修改一个参数并导出glb格式,再串行执行10次花费的时间是22s
并发情况下,同时执行10次,花费时间是5.3s
执行20次的情况对应的是无并发为44.8s,并发是8.6s
Intel(R)Core(TM)i9-10900KCPU@_3.70GHz\10——CPU是20核测试结果
package main
import (
"context"
"fmt"
"bytes"
"os/exec"
"sync"
"time"
// "github.com/sourcegraph/conc"
)
// 无并发执行主程序,串行执行
func main() {
start := time.Now()
values := []string{"200", "300", "400", "500", "600", "700", "800", "900", "1000", "1100"}
for _, url := range values {
convertfc2(url)
}
elapsed := time.Since(start)
fmt.Println(elapsed) // 22.3215616s
}
// 并发执行主程序
func main_back2() {
start := time.Now()
wg := &sync.WaitGroup{}
values := []string{"200", "300", "400", "500", "600", "700", "800", "900", "1000", "1100"}
ctx, cancel := context.WithCancel(context.Background())
for _, url := range values {
wg.Add(1)
subCtx := context.WithValue(ctx, favContextKey("url"), url)
go convertfc(subCtx, wg)
}
go func() {
// time.Sleep(time.Second * 1)
time.Sleep(1)
cancel()
}()
wg.Wait()
elapsed := time.Since(start)
fmt.Println(elapsed) // 5.3394626s
}
// 无并发修改参数导出模型
func convertfc2(parameter string) {
arg := []string{"-i", "d:\\goroutetest.fcstd", "-o", "d:\\" + parameter + ".glb", "-p", parameter}
fmt.Println("-----convertfc--arg-------", arg)
cmd := exec.Command("D:/convertfc.exe", arg...)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
// cmd.Stderr = os.Stderr
cmd.Stderr = &stderr
err := cmd.Run()
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
fmt.Printf("out:\n%s\n err:\n%s\n", outStr, errStr)
if err != nil {
fmt.Printf("cmd.Run() failed with %s\n", err)
}
}
// 并发修改参数导出模型
func convertfc(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
url, _ := ctx.Value(favContextKey("url")).(string)
for {
select {
case <-ctx.Done():
fmt.Printf("stop getting url:%s\n", url)
return
default:
arg := []string{"-i", "d:\\goroutetest.fcstd", "-o", "d:\\" + url + ".glb", "-p", url}
fmt.Println("-----convertfc--arg-------", arg)
cmd := exec.Command("D:/convertfc.exe", arg...)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
// cmd.Stderr = os.Stderr
cmd.Stderr = &stderr
err := cmd.Run()
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
fmt.Printf("out:\n%s\n err:\n%s\n", outStr, errStr)
if err != nil {
fmt.Printf("cmd.Run() failed with %s\n", err)
}
}
}
}
最后编辑:秦晓川 更新时间:2024-11-14 14:45