PLM之家PLMHome-工业软件与AI结合践行者

Catia二次开发源码分享: 通过鼠标点击创建直线

[复制链接]

2017-4-17 21:56:09 4860 0

admin 发表于 2017-4-17 21:56:09 |阅读模式

admin 楼主

2017-4-17 21:56:09

请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!

您需要 登录 才可以下载或查看,没有账号?注册

x

% L2 A! @* u( H6 c5 i7 q% A; o0 `Catia二次开发源码分享: 通过鼠标点击创建直线
2 l5 T$ B# E! H' R5 w
1 a, y; ~, m7 `1 ?! ^1 d( O$ y: |% g3 b. C) V9 _

( K5 A! R/ C" l+ v! K#include "CAARCCreateLine.h"
# {' J" j9 E) R#include "CATIndicationAgent.h"1 Y) H; `' o6 d3 `5 `" w
#include "CATMathPlane.h"9 c" v% x8 X( Z

6 s$ ?) X6 b+ P/ T#include "CATCreateExternalObject.h"
! ^* E6 C" @) e; v% ?: q4 u
0 X, M+ [+ j1 i$ N  s#include "CATMathPoint2D.h"; O$ |  B* t" Q* Y
#include "CATMathPoint.h"
, |3 u& H. N6 q#include "CATMathPlane.h"; G9 G# n- g' m& O/ `
- L$ t( Q7 w" r8 W5 D/ ^% R& P
#include "CATIGSMPoint.h"
& \4 K5 ~' o0 B#include "CATIGSMLinePtPt.h"- V7 z, @% p" ?- [3 X* W# ]
) C' ]; W/ e: N
#include "CATFrmEditor.h"
" Y9 q! F8 B' l; r# n- _/ B* e#include "CATPathElement.h"
) h0 E8 D* E$ {0 h7 |% Y& u  B. W! E& p2 _9 I2 E7 N. g
#include "CATIProduct.h"
! S6 d( J4 s; E9 h7 H#include "CATILinkableObject.h". v4 O3 ^4 l6 {
#include "CATDocument.h"
& W' X0 R- @1 y/ g4 E& t# Y. @% G, A
, x8 q5 y& ?& |' {. W$ O* q6 ~#include "CATIContainerOfDocument.h"
6 U: J9 N& ]1 ?
5 w( n  D0 o' a5 A( r% y# A#include "CATIGSMProceduralView.h"( L. }; y, c3 h; X
, F: ~& w  Z/ e7 B
#include "CATIContainer.h"
0 |  k! m8 D1 w7 L3 \#include "CATIGSMFactory.h"
5 {6 I3 m2 o% R, d4 [( [: W/ T4 {- @- b+ o5 j. r1 B4 F* A: d
#include "CATISpecObject.h"
7 T0 {( G! L: f. BCATCreateClass( CAARCCreateLine);
9 |' @4 h  O" R# A; B) |( n  q
2 r3 L% v' K$ r1 f7 j/ U' _2 i) M
//-------------------------------------------------------------------------
" g+ b) d, ]8 r// Constructor/ H+ p6 n# r% b/ t6 |+ ?
//-------------------------------------------------------------------------
# f% d6 p+ v! P+ i& a* e0 I1 qCAARCCreateLine::CAARCCreateLine() :
! Y# W6 h4 W/ `& P2 E  CATStateCommand ("CAARCCreateLine", CATDlgEngOneShot, CATCommandModeExclusive)
3 _2 _5 `  [) u% C//  Valid states are CATDlgEngOneShot and CATDlgEngRepeat
; g/ N- O& |, t7 Q: {  ,_IndicationOnePoint(NULL),_IndicationTwoPoint(NULL)
" J- k6 i6 f. j9 X: K! |{
! r9 k! Y' h' o7 ^# q  i- Q1 I$ I}
, K) y& ~+ S  V& y  r( ]% C2 B  x
8 L* w% t% z7 b//-------------------------------------------------------------------------
: n$ R9 B; j& z& E7 K9 y// Destructor# j4 C3 C  }; z! l4 p
//-------------------------------------------------------------------------
0 H; e; x2 S( n# W. iCAARCCreateLine::~CAARCCreateLine()& H3 R# i& f7 Y. F( ~  k% W
{6 ^/ q3 v% `' u) r) C
   if (_IndicationOnePoint != NULL)
% \. `, U, q. b+ q5 Z& I4 N      _IndicationOnePoint->RequestDelayedDestruction();7 c- B4 N- v. n9 z# @% r
   if (_IndicationTwoPoint != NULL)
+ T' t, m4 ^) l$ i; c; y; q) f     _IndicationTwoPoint->RequestDelayedDestruction();
4 c4 z  l4 W- y4 y: _6 S}
0 u' o$ i( W0 I2 ~7 U. p
0 b7 _2 b, Y* O: B! U( l7 K) n+ D8 N3 W. F9 Y% @/ ?
//-------------------------------------------------------------------------
% l! o' y" r- x// BuildGraph()
2 D5 I: M3 A1 |" X4 \//-------------------------------------------------------------------------% h- ^& v2 V6 l# _
void CAARCCreateLine::BuildGraph()
' t& i- B' M7 Q# p7 l3 h1 S7 d{/ X2 N2 I* T' K2 E2 p; d7 G
3 w0 u- S* _( C* F
1 l. R% f4 D8 ?5 ~  h" s
  // TODO: Define the StateChart
* [& V! V# U6 \# T8 ]- _4 o  // ---------------------------
2 {, m5 a: E) C/ b' S$ m+ Y  _IndicationOnePoint = new CATIndicationAgent ("IndicationOnePoint");5 S: @, u, s8 h$ j7 k" V) I
  AddCSOClient(_IndicationOnePoint);
; m3 u" E& N8 F& h2 ?+ S- l
# v  N* \) ?0 e. g! S8 s5 x/ t  _IndicationTwoPoint = new CATIndicationAgent ("IndicationTwoPoint");, s& ]$ Y5 J1 y2 }; D# P- }
& {  }8 N" b) m
  CATMathPlane PlaneXY;" X3 g# q4 j' U
  _IndicationOnePoint -> SetMathPlane (PlaneXY);, L/ s* s- x8 l- u8 A* W
  _IndicationTwoPoint -> SetMathPlane (PlaneXY);
" |% Z/ u4 [+ B# |
6 X6 R/ S4 B4 r: C, Q/ U  CATDialogState * initialStateOne = GetInitialState("选择第一个点位置");
6 T# E! j6 \3 f  D' p8 L  initialStateOne -> AddDialogAgent (_IndicationOnePoint);
8 q( Z1 f  {% v! A3 z2 h
" a* S* ?  c1 K$ s' ?2 D' k3 u  CATDialogState * initialStateTwo = AddDialogState("选择第二个点位置");
' _) c' [1 z/ P  ^  initialStateTwo -> AddDialogAgent (_IndicationTwoPoint);1 b5 y4 U! j  X4 c2 h3 m4 D2 j

7 M6 i& J/ x4 l4 Y( M, B  AddTransition( initialStateOne,
4 ~# w* u5 c" w& m0 B) n( F- R                 initialStateTwo, 1 d- @. L; F, F; L; {0 X6 g
                 IsOutputSetCondition (_IndicationOnePoint),
# m5 J, C3 q+ p                 Action ((ActionMethod) &CAARCCreateLine::ActionOne));
# Z: r; @6 G3 n! s" s5 u) O3 v2 b9 C. y
  AddTransition( initialStateTwo,
2 p$ k$ i9 Z$ E+ s; N' y( ?4 t6 `% M                NULL,
% Z, _+ x. _' X: y9 D                IsOutputSetCondition (_IndicationTwoPoint),
% C) _$ f) w. o% W! c                Action ((ActionMethod) &CAARCCreateLine::ActionTwo));
, s6 _8 |! {6 h8 `; V5 e4 A}
: w' |, u# j6 {, O! G% V" M! E3 h4 `8 ^! J+ e

+ N! ?" l) f. G) D//-------------------------------------------------------------------------
! {$ K) Q4 X$ W// ActionOne ()/ N! q! R/ K5 N8 t! S! ?, f
//-------------------------------------------------------------------------/ w2 e2 U8 u5 t  f3 c4 G: A
CATBoolean CAARCCreateLine::ActionOne( void *data )
9 L* `" x$ W& N& r9 {{) o6 _5 F4 i3 x: Y! H
  // TODO: Define the action associated with the transition
7 ^+ l+ N: R& G  // ------------------------------------------------------
% S9 {( _, B( x  CATMathPoint2D point2D = _IndicationOnePoint->GetValue();//获得一个2D的点4 }/ {0 m4 m! B/ D; W% C6 Q0 X3 {9 p2 b5 I
. U# Y; z& N. g* G. M
  CATMathPoint Point3D;
# `$ _( z; B' P/ \8 ~8 v) [9 D  CATMathPlane Plane = _IndicationOnePoint->GetMathPlane();
+ J" o" u8 {: ^) Q' `1 _6 q3 f- u0 ]5 h( Q$ n" |& X+ _( [! Z
  Plane.EvalPoint(point2D.GetX(),point2D.GetY(),Point3D);                //将2D点转换为3D点: v7 c+ }$ t- s; X

! i; W/ A$ @3 c  //设置Container(非根节点)
. O3 B. o0 f$ d# {  //获得Editor
# o! W4 ^* `2 |  CATFrmEditor* pEditor = CATFrmEditor::GetCurrentEditor();
* V- W- m5 d4 P3 b5 F
3 u# e. X/ s: {3 \, A  //得到当前对象的文档
1 J+ E5 l* e& }( J# n1 o, u4 _% i2 ~  CATDocument * pDocument = NULL ;
- A' d6 ?0 t! H2 N) S' ?% Q: N4 V$ C4 f5 \! t2 o" y$ T
  //取得当前活动对象! E' l+ o6 s) k2 f* A6 e& Y; z5 _
  CATPathElement activePath = pEditor->GetUIActiveObject();! f1 [3 I8 [; C4 Y0 a$ ?4 f! k

9 j7 J0 j6 ?8 V% e1 K+ l  //取得当前活动的product+ Y" i! E0 `* Y3 v
  CATIProduct *pActiveProduct = (CATIProduct *)activePath.SearchObject(CATIProduct::ClassName());
/ z' ^0 J5 A4 n' s. q' n4 F
% b  b2 X. `% t% D$ d5 E1 [( ~( ^  //当前活动对象不存在
2 M7 P8 f' y, P, o  if (pActiveProduct == NULL)  I3 N7 [2 s# i9 q" c
  {4 `8 a+ `/ F  v3 K
    pDocument = pEditor->GetDocument();! |+ Q. |' v3 j/ X
  }9 f4 p1 S3 o: ^: Y+ ~, i
  else/ {* P( J' }0 x4 W: l, N, t
  {# j6 R& J, _1 l" E5 |
    CATIProduct_var spRef = pActiveProduct->GetReferenceProduct();
" S3 I8 }, L, c, ?% Q    //当前对象的引用对象是否存在% s# Z+ X% n  s+ _3 h, p
    if ( NULL_var == spRef )8 c$ a" d# m& e% k, O8 A1 C6 {
    {
' _3 v! g3 |) K" J2 z6 I: G) ], M5 ?      return FALSE;
: r0 C' Y# J8 f9 Q- C2 l% L    }
! i; x6 G8 y! e! G9 U
7 h/ k) @/ a; \& y    //当前对象的链接对象
- b1 _6 E; @' G* v9 q    CATILinkableObject * piLinkableObject = NULL;# @! I8 E- ^7 U5 T; v
    HRESULT rc = spRef->QueryInterface( IID_CATILinkableObject, (void**)& piLinkableObject );                            ; v, f5 ]' ]% O* \) K8 N. T
    if ( FAILED(rc) )
" y$ S* {* E- R* ~5 }9 j8 m  j6 ?    {1 G6 j% O3 N0 f0 o+ {
      piLinkableObject->Release();
4 n, J- `6 j5 B7 J      piLinkableObject = NULL ;
/ H# m' Q; x7 g) F      return FALSE;1 h$ \0 _/ K2 s9 {( T: G
    }5 X$ R& @8 C$ B9 }. P* z  C* o7 o9 X

. S4 p8 J- S! T4 \, V  S    //得到当前对象的文档
8 ?, m7 O0 l" i  o, q% r3 b- H    pDocument = piLinkableObject->GetDocument();0 H: [' y2 r& d
    piLinkableObject->Release();" o# r1 f. u+ D* f: y
    piLinkableObject = NULL ;( R1 M5 R+ W% U4 X
3 X* s' N! h" C  l) s
    if ( NULL == pDocument)
; T  I1 D$ M9 i    {
/ a* B) m  F9 o      return FALSE;) r: [- J# v9 z/ ]& M4 @% ]
    }
6 q  E3 s& k5 b9 s! W& l/ |  Y  }" }3 V* U; q/ m1 _! u0 H: h

: Z% j7 L9 q0 h3 c9 q  //得到文档容器集
' g7 C  u  B# d5 X  CATIContainerOfDocument * pIContainerOfDocument = NULL;
" ^1 f+ y% M5 h1 l; ?& o  HRESULT rc = pDocument->QueryInterface(IID_CATIContainerOfDocument, (void**)&pIContainerOfDocument);3 R/ y. ?$ d' x1 y- _+ a$ ~
  if (FAILED(rc))! L% N- l4 g, b$ i8 ^
  {7 T" J" ^/ n2 k
    //pIContainerOfDocument->Release();0 r5 {$ J3 X; I9 @2 F& V+ {
    pIContainerOfDocument = NULL ;
! E9 b( M! F# S1 A) E8 ]1 ]    return FALSE;9 N" y0 |5 y0 ]) p4 `1 f3 z# {5 z$ _
  }! V5 l8 x1 @) O# e- A8 y

! i( s2 {1 P- G  //获得Document6 v1 K3 j8 ~4 N! q2 i; ^0 b) e
  CATIContainer* _pContainer = NULL;        8 X( i  o8 p9 `
  //获得SpecContainer2 x. n) ]4 _! B
  HRESULT hr = pIContainerOfDocument->GetSpecContainer(_pContainer);) |! g! x2 m5 A' y8 x
       
1 v& g# A' ?' c  //GSM工厂
& F+ a9 G1 `4 K. a) Z' C: \  CATIGSMFactory_var spGSMFactory = NULL_var;7 `/ w0 y+ z* u) Z+ S+ O9 T4 A) ^
  //设置工厂               
! z" ~( S  _1 [4 ~8 h  spGSMFactory = _pContainer;                                                                        & A0 B1 V4 y/ @* T& P9 W% X
6 X& H. l1 S; U" _% H: b
  CATIGSMPoint_var spPoint = spGSMFactory->CreatePoint(Point3D);0 [7 D) d: X8 c* G

* @: y; m, ]* p8 U  spSpecPoint1= spPoint;                                       
" ]2 R5 c, s! u" Z: b; B% L0 j+ I! e9 y( ~+ Y+ C6 A
  CATIGSMProceduralView_var spSndPntObj = spSpecPoint1;' |1 y5 X! A" ]% ?4 \! m9 q
4 f( x1 q; r/ g+ z1 ?
  //*将点显示在屏幕上. X; |6 L+ H; Y% |, r
  spSndPntObj->InsertInProceduralView();
' v. b- |5 u* r8 z/ h5 H: n8 S4 H! X: P
  spSpecPoint1->Update();
  |2 T( k- @/ u) o0 o$ V% `, m: x8 W( |1 ~2 s- O2 c
  return TRUE;/ U0 d1 }; S% w; N
}
$ v1 z' o* v$ \# H$ h6 }6 `. S7 H* R0 [! V8 k1 l
//-------------------------------------------------------------------------
5 u% ~! F  D/ S' H  \// ActionTwo ()
: t9 N' j6 F$ b2 x0 I4 t1 V//-------------------------------------------------------------------------
6 `9 F5 n, v; i8 {1 sCATBoolean CAARCCreateLine::ActionTwo( void *data ); B5 Z1 d2 N3 I7 Z1 L  ]! s
{  ~1 p2 k7 _4 E8 Y4 X0 M' ]
  // TODO: Define the action associated with the transition
) c5 E5 T) C, l$ d, d  // ------------------------------------------------------
2 I: w+ B" u* r9 s; W  CATMathPoint2D point2D = _IndicationTwoPoint->GetValue();//获得一个2D的点
- v1 X. @+ W8 x; U4 t" f8 _$ h
  CATMathPoint Point3D;' u, H3 ]3 u3 y4 t3 P! T( H
  CATMathPlane Plane = _IndicationTwoPoint->GetMathPlane();' {! e9 G( g' i  R
- {; y1 ?, C+ J  x" A1 b  q: N
  Plane.EvalPoint(point2D.GetX(),point2D.GetY(),Point3D);                //将2D点转换为3D点
) E( f3 H2 P' u: A( a2 g; X. y7 u) O
  //设置Container(非根节点)" r' A$ ^% U0 n
  //获得Editor* k/ w+ U: c6 r0 o  n7 e/ g2 W
  CATFrmEditor* pEditor = CATFrmEditor::GetCurrentEditor();
, f! F+ g' P, w2 u) E
8 b7 j+ e' g5 T% L% q! [) P7 g5 y! C  //得到当前对象的文档% ?( t+ |. O3 W" H. J# l, w
  CATDocument * pDocument = NULL ;
% y* f, n2 u- W/ T( P$ O7 T3 V# ]1 U0 }
  //取得当前活动对象
. C1 r" I7 @3 m" d" k  CATPathElement activePath = pEditor->GetUIActiveObject();
: l. ]; ~1 g9 @8 z4 i' z0 Z% }  Y0 c7 {5 ^/ b
  //取得当前活动的product
& x" W; l  o$ @2 D1 n  CATIProduct *pActiveProduct = (CATIProduct *)activePath.SearchObject(CATIProduct::ClassName());4 m8 x) b0 K+ j5 S* X4 P

' Z* Y/ H! a9 G( i6 u1 {) |1 U  //当前活动对象不存在
) b# ]' M* j- z) V1 b2 E: S  if (pActiveProduct == NULL)% \9 k, E3 {6 L4 L% W* k. D
  {3 b9 Y& [1 q, A' E& U1 j& k
    pDocument = pEditor->GetDocument();; f# h4 k0 n% v( T% X0 W
  }
! E3 x4 Q: i9 Z3 R2 L) Q. M  else
# f! X1 j* X2 g+ V; x4 \& u  {- a' r/ p  v' p) t7 d% z. p: x8 J
    CATIProduct_var spRef = pActiveProduct->GetReferenceProduct();4 F2 y3 N7 H1 |$ i* }
    //当前对象的引用对象是否存在/ h1 k" j9 p, \) k2 a) `3 @- L% n
    if ( NULL_var == spRef )! v1 g  v+ V. _; p  g; j
    {; R; l% m5 \7 t  {
      return FALSE;
6 _2 d, S$ \# |; D1 Z+ }    }
+ C1 T3 n/ [5 e: I5 \) |1 E1 x: I# k- s
    //当前对象的链接对象4 j- S2 J3 z7 z9 x
    CATILinkableObject * piLinkableObject = NULL;
: A3 s# }/ u/ Z9 _+ |, B    HRESULT rc = spRef->QueryInterface( IID_CATILinkableObject, (void**)& piLinkableObject );                            8 E% p9 K9 j5 r4 ?* F. ~* i5 _
    if ( FAILED(rc) )
% [5 w- h$ d, u7 b    {% Q8 R- f& L: N
      piLinkableObject->Release();
' Q/ l$ ~. L! l9 C# o      piLinkableObject = NULL ;# s  [: `3 a6 t- J$ G& B
      return FALSE;- R4 c& K& z, [% m( N2 m  B
    }6 ]' |, I/ U! \, h6 f2 X6 V

; F+ h* J4 Z9 I, d) I' p" _) t    //得到当前对象的文档1 x  [# ~2 ^" s% Q0 D
    pDocument = piLinkableObject->GetDocument();
- `: p' x& A( R6 H. L! `" A8 x    piLinkableObject->Release();
  p' E2 H0 ~7 ?8 Q8 r* `    piLinkableObject = NULL ;
; K& s: |7 |7 _5 O! L4 \8 i& W$ x& p- U# \1 ~' O! u
    if ( NULL == pDocument)" H& Q7 M6 l! k# s1 E1 B
    {4 x/ n$ ^" p1 F8 @7 p2 N
      return FALSE;2 p2 ^* z3 _" q( z: H
    }
* _+ z( U" g: q& K, i( i4 b  }
2 f: I* n+ K1 e9 y* g5 m# r9 |1 ~" S: [& T
  //得到文档容器集
8 v, a% Q3 y; ~. h# A  CATIContainerOfDocument * pIContainerOfDocument = NULL;3 ?8 A8 O7 B$ s/ @: f: o
  HRESULT rc = pDocument->QueryInterface(IID_CATIContainerOfDocument, (void**)&pIContainerOfDocument);! v( e0 S. B6 V0 r: [2 d/ k4 C$ W
  if (FAILED(rc))
3 I# m8 j" S* g. V! K$ j% R9 q  {: J( u9 I0 p7 X4 T
    //pIContainerOfDocument->Release();9 C! `' _& l3 h5 t& W1 I
    pIContainerOfDocument = NULL ;
- g: r' t& j3 \/ S! ^    return FALSE;$ Z3 ^  i  W- B9 F+ d5 S$ s3 i
  }
: J. c' _" ^: p7 C1 l6 s" B
2 H5 W4 l" {% Q8 l" B  //获得Document) V! f! n2 _4 X$ ]
  CATIContainer* _pContainer = NULL;       
" @* l% _' B' s# T  //获得SpecContainer) G: w. F% k$ o
  HRESULT hr = pIContainerOfDocument->GetSpecContainer(_pContainer);' W) p# T4 b, K# f2 Z. W
        ' Q. |9 A$ `7 i7 @6 C; g
  //GSM工厂
" }) V; P) i' @% m9 p  CATIGSMFactory_var spGSMFactory = NULL_var;+ ]( O6 s! F2 ^5 b& R
  //设置工厂                / H4 }0 i- M/ D3 b9 B) V. i. v% ?
  spGSMFactory = _pContainer;                                                                        , s3 e! ]$ T; |% t/ `* Q7 @
) J+ d/ v. K" S
  CATIGSMPoint_var spPoint = spGSMFactory->CreatePoint(Point3D);' F5 G# x/ M$ J! @( B6 B

. k" J$ Q. c( L1 J6 S1 k  CATISpecObject_var spSpecPoint2= spPoint;                                       
/ e0 x4 i- {& F2 C# I) i5 D/ M$ ]5 R3 |/ ?4 _5 M0 c3 r
  CATIGSMProceduralView_var spSndPntObj = spSpecPoint2;
" G0 W0 t8 e0 U2 j, L
2 X8 D' H4 g' M. c9 N  //*将点显示在屏幕上" N5 W7 e- V$ T; b: g; [4 G
  spSndPntObj->InsertInProceduralView();
0 W4 C  s1 U3 G* W- }% c4 h: y
" P$ ]  }) E, n  D  spSpecPoint2->Update();* t  b5 f, C+ I5 Q* n
: J4 C0 w+ \! T; @( o" b8 k
  //生成线
  ~$ C4 d0 ]7 w" ?/ N" S# k  CATIGSMLinePtPt_var spLine = spGSMFactory->CreateLine(spSpecPoint1, spSpecPoint2, NULL_var);8 N5 `+ K: t$ b+ S) N
2 U- H/ w* H" P# \; S
  CATISpecObject_var spSpecLine= spLine;                                       
- P- [! b3 n- L$ T. H: J3 E# h
5 A# F0 B2 ]# R8 K+ O1 V1 P9 p0 F  CATIGSMProceduralView_var spSndPntObjLine = spSpecLine;+ v# K  A# \# `0 m# j+ r% T

! D# T* y" R3 M2 L6 D3 s: ]  //*将线显示在屏幕上' ~  {$ D+ @& d9 _4 [( G
  spSndPntObjLine->InsertInProceduralView();: Q, t  J& A. n8 D5 C6 C
6 T/ n* \- z/ ?! f& Q
  spSpecLine->Update();# V" R/ D( C: m% [! q

$ ~; i5 |# q( i# t. b  return TRUE;
9 G# Q3 Q3 g- m0 m/ L}1 {/ w) _, B5 E0 T5 |( u4 w
/ E5 U, p8 B7 y# ?# ]
9 J* X4 e1 v( k2 m2 f% f
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 doTeam.tech
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 注册

返回列表 本版积分规则

  • 发布新帖

  • 在线客服

  • 微信

  • 客户端

  • 返回顶部

  • x
    温馨提示

    本网站(plmhome.com)为PLM之家工业软件学习官网站

    展示的视频材料全部免费,需要高清和特殊技术支持请联系 QQ: 939801026

    PLM之家NX CAM二次开发专题模块培训报名开始啦

    我知道了