[C# SolidWorks API] ロフトを使ったモデリング
スケッチした形状を断面形状としてロフト機能を利用すると,さまざまな形状をモデリングすることができます.試しに,”SolidWorks Loft”でGoogle検索するとこのような形状を見つけることができました.そんな重要かつ便利なロフト機能をAPIから使ってみましょう.
下面と上面の断面形状をスケッチして,ロフト機能で3次元形状を作ってみます.今回は簡単のため,断面形状は大きさの異なる四角形としましょう.
ロフト機能で3次元形状を作る手順は次の通りです.
1.下面の断面形状をスケッチする
2.上面をスケッチするための参照面を作成する
3.参照面に上面の断面形状をスケッチする
4.下面と上面をつなぐガイドカーブを作成する
5.ロフト機能で下面と上面をつなぐ
1と3の断面形状のスケッチは[C# SolidWorks API] 四角形をスケッチするを参考にしてください.
コーディングでは,次の3つのメソッドを定義します.
1.基準となるoriginePlaneから距離distanceだけ離れた位置に参照面を作成するメソッド
createReferencePlane(string originPlane, double distance)
2.上下面の名前bottomSketchName,topSketchNameと断面寸法からガイドカーブを作成するメソッド
string sketchGuideCurve(string bottomSketchName, string topSketchName,
double bWidth, double bHeight, double tWidth, double tHeight, double height)
3.上下面とガイドカーブの名前からロフトを実行するメソッド
loft(string bottomSketchName, string topSketchName,
string guideCurveSketchName)
上下面とガイドカーブの寸法,位置関係については,下の図を参照してください.
実行例
下面: bWidth = 0.2 m, bHeight = 0.2 m
上面: tWidth = 0.4 m, tHeight = 0.1 m
Height = 1.0 [m]
として,3次元形状を作成した様子です.基準面には”平面”を指定しています.
コード
全体のプログラムは次のようになります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // for SolidWorks API using SolidWorks.Interop.cosworks; using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; // for Debuging using System.Diagnostics; namespace swLoft { class Program { SldWorks.ISldWorks swApp = null; IModelDoc2 modelDoc = default(ModelDoc2); void startSW() { swApp = new SldWorks.SldWorks(); Debug.Assert(swApp != null); swApp.Visible = true; } void createNewPartDocument() { string partTemplate = swApp.GetUserPreferenceStringValue((int)swUserPreferenceStringValue_e.swDefaultTemplatePart); if ((partTemplate != null) && (partTemplate != "")) { modelDoc = (IModelDoc2)swApp.NewDocument(partTemplate, (int)swDwgPaperSizes_e.swDwgPaperA2size, 0.0, 0.0); } } string sketchRectangle(string planeName, double width, double height) { string sketchName = null; IModelDocExtension dExt = (IModelDocExtension)modelDoc.Extension; bool isSelected = dExt.SelectByID2(planeName, "PLANE", 0, 0, 0, false, 0, null, 0); if (isSelected) { ISketchManager sketchMgr = modelDoc.SketchManager; double halfWidth = width / 2.0; double halfHeight = height / 2.0; sketchMgr.InsertSketch(true); sketchMgr.CreateCornerRectangle(-halfWidth, halfHeight, 0, halfWidth, -halfHeight, 0); sketchMgr.InsertSketch(true); sketchName = getItemName("SKETCH", -halfWidth, 0, halfHeight); } return sketchName; } string sketchGuideCurve(string bottomSketchName, string topSketchName, double bWidth, double bHeight, double tWidth, double tHeight, double height) { string sketchName = null; IModelDocExtension dExt = (IModelDocExtension)modelDoc.Extension; bool isSelected = dExt.SelectByID2("Point1@" + bottomSketchName, "EXTSKETCHPOINT", 0, 0, 0, false, 1, null, 0); Debug.Assert(isSelected); isSelected = dExt.SelectByID2("Point1@" + topSketchName, "EXTSKETCHPOINT", 0, 0, 0, true, 1, null, 0); Debug.Assert(isSelected); modelDoc.Insert3DSplineCurve(false); double bottomW = bWidth / 2.0; double bottomH = bHeight / 2.0; double topW = tWidth / 2.0; double topH = tHeight / 2.0; sketchName = getItemName("EDGE", -(topW + bottomW) / 2.0, height / 2.0, -(topH + bottomH) / 2.0); return sketchName; } string createReferencePlane(string originPlaneName, double distance) { string refPlaneName = null; IModelDocExtension dExt = (IModelDocExtension)modelDoc.Extension; // Create Reference Plane bool isSelected = dExt.SelectByID2(originPlaneName, "PLANE", 0, 0, 0, false, 0, null, 0); if (isSelected) { IFeatureManager featureMgr = (IFeatureManager)modelDoc.FeatureManager; IRefPlane rPlane = (IRefPlane)featureMgr.InsertRefPlane((int)swRefPlaneReferenceConstraints_e.swRefPlaneReferenceConstraint_Distance, distance, 0, 0, 0, 0); refPlaneName = getItemName("PLANE", 0, distance, 0); } return refPlaneName; } void loft(string bottomSketchName, string topSketchName, string guideCurveSketchName) { IModelDocExtension dExt = (IModelDocExtension)modelDoc.Extension; bool isSelected = dExt.SelectByID2(bottomSketchName, "SKETCH", 0, 0, 0, false, 1, null, 0); Debug.Assert(isSelected); isSelected = dExt.SelectByID2(topSketchName, "SKETCH", 0, 0, 0, true, 1, null, 0); Debug.Assert(isSelected); isSelected = dExt.SelectByID2(guideCurveSketchName, "REFERENCECURVES", 0, 0, 0, true, 2, null, 0); Debug.Assert(isSelected); IFeatureManager featureMgr = (IFeatureManager)modelDoc.FeatureManager; featureMgr.InsertProtrusionBlend2(false, true, false, 1, 0, 0, 1, 1, true, true, false, 0, 0, 0, true, true, true, (int)swGuideCurveInfluence_e.swGuideCurveInfluenceNextGlobal); } void createShape(double bWidth, double bHeight, double tWidth, double tHeight, double height) { // Sketch Bottom string bottomSketchName = sketchRectangle("平面", bWidth, bHeight); // Sketch Top string refPlaneName = createReferencePlane("平面", height); string topSketchName = sketchRectangle(refPlaneName, tWidth, tHeight); // Sketch Guide Curve string guideCurveSketchName = sketchGuideCurve(bottomSketchName, topSketchName, bWidth, bHeight, tWidth, tHeight, height); // Loft loft(bottomSketchName, topSketchName, guideCurveSketchName); } string getItemName(string type, double x, double y, double z) { string featureName = null; IModelDocExtension dExt = modelDoc.Extension; // まず,選択する bool status = dExt.SelectByID2("", type, x, y, z, true, 0, null, 0); if (status) { // 対象を取得する IFeature feature = (IFeature)(modelDoc.SelectionManager).getSelectedObject6(1, -1); // 選択を解除する modelDoc.ClearSelection2(true); Debug.Assert(feature != null); string fType = null; featureName = feature.GetNameForSelection(out fType); Debug.Print(fType + ": " + featureName); } return featureName; } void setView(int viewType) { modelDoc.ShowNamedView2("", viewType); modelDoc.ViewZoomtofit2(); } static void Main(string[] args) { Program p = new Program(); p.startSW(); p.createNewPartDocument(); Console.WriteLine("Creating Shape"); double bWidth = 0.2; double bHeight = 0.2; double tWidth = 0.4; double tHeight = 0.1; double height = 1.0; p.createShape(bWidth, bHeight, tWidth, tHeight, height); p.setView((int)swStandardViews_e.swIsometricView); } } } |
解説
コードを詳しく見ていきましょう.
2.上面をスケッチするための参照面を作成する
createRefencePlaneは,基準となる面の名前originPlaneNameと距離distanceを指定して,参照面を作成するメソッドです.戻り値は,新しく作成した面の名前です.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
string createReferencePlane(string originPlaneName, double distance) { string refPlaneName = null; IModelDocExtension dExt = (IModelDocExtension)modelDoc.Extension; // Create Reference Plane bool isSelected = dExt.SelectByID2(originPlaneName, "PLANE", 0, 0, 0, false, 0, null, 0); if (isSelected) { IFeatureManager featureMgr = (IFeatureManager)modelDoc.FeatureManager; IRefPlane rPlane = (IRefPlane)featureMgr.InsertRefPlane((int)swRefPlaneReferenceConstraints_e.swRefPlaneReferenceConstraint_Distance, distance, 0, 0, 0, 0); refPlaneName = getItemName("PLANE", 0, distance, 0); } return refPlaneName; } |
7行目:基準面を取得しています.
9行目:フィーチャマネージャを取得しています.
10行目:フィーチャマネージャのInsertRefPlaneメソッドを使って,参照面を作成しています.
第1引数で,条件として距離を設定しています.swRefPlaneReferenceConstraints_e.swRefPlaneReferenceConstraint_Distance
第2引数で,距離の値を指定しています.
13行目:参照面の名前を取得しています(平面1など).
4.下面と上面をつなぐガイドカーブを作成する
sketchGuideCurveは,上下面の名前と断面寸法からガイドカーブを作成するメソッドです.戻り値は,新しくガイドカーブの名前です.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
string sketchGuideCurve(string bottomSketchName, string topSketchName, double bWidth, double bHeight, double tWidth, double tHeight, double height) { string sketchName = null; IModelDocExtension dExt = (IModelDocExtension)modelDoc.Extension; bool isSelected = dExt.SelectByID2("Point1@" + bottomSketchName, "EXTSKETCHPOINT", 0, 0, 0, false, 1, null, 0); Debug.Assert(isSelected); isSelected = dExt.SelectByID2("Point1@" + topSketchName, "EXTSKETCHPOINT", 0, 0, 0, true, 1, null, 0); Debug.Assert(isSelected); modelDoc.Insert3DSplineCurve(false); double bottomW = bWidth / 2.0; double bottomH = bHeight / 2.0; double topW = tWidth / 2.0; double topH = tHeight / 2.0; sketchName = getItemName("EDGE", -(topW + bottomW) / 2.0, height / 2.0, -(topH + bottomH) / 2.0); return sketchName; } |
6行目:上面(topSketchName)の点(Point1)を選択リストに追加しています.SelectByID2の第1引数が名前,第2引数が種類です.第6引数がfalseであることにも注意してください.一度選択リストを空にしてから追加しています.
9行目:下面(bottomSketchName)の点(Point1)を選択リストに追加しています.SelectByID2の第6引数がtrueであることに注意してください.現状のリストに選択した対象を追加しています.
12行目:Insert3DSplineCurveでカーブを作成しています.引数がfalseなので,カーブは閉じていません.
5.ロフト機能で下面と上面をつなぐ
loftは,上下面とガイドカーブの名前を指定して,ロフトを実行するメソッドです.戻り値はありませんが,スケッチやカーブ同様名前を返すようにしておくと便利だと思います.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void loft(string bottomSketchName, string topSketchName, string guideCurveSketchName) { IModelDocExtension dExt = (IModelDocExtension)modelDoc.Extension; bool isSelected = dExt.SelectByID2(bottomSketchName, "SKETCH", 0, 0, 0, false, 1, null, 0); Debug.Assert(isSelected); isSelected = dExt.SelectByID2(topSketchName, "SKETCH", 0, 0, 0, true, 1, null, 0); Debug.Assert(isSelected); isSelected = dExt.SelectByID2(guideCurveSketchName, "REFERENCECURVES", 0, 0, 0, true, 2, null, 0); Debug.Assert(isSelected); IFeatureManager featureMgr = (IFeatureManager)modelDoc.FeatureManager; featureMgr.InsertProtrusionBlend2(false, true, false, 1, 0, 0, 1, 1, true, true, false, 0, 0, 0, true, true, true, (int)swGuideCurveInfluence_e.swGuideCurveInfluenceNextGlobal); } |
5,8,11行目:選択する対象の名前と種類を指定して,下面,上面,ガイドカーブを選択しています.SelectByID2の第6引数が上からtrue,false,falseとなっている点にも注意してください.
15行目:InsertProtrusionBlend2で,ロフトを実行しています.各引数の意味は,APIのヘルプに加えて,ロフトPropertyManagerを参考にすると理解しやすいと思います.
まとめ
基準面とそこからの距離をもとにして,参照面を作成する方法を説明しました.
2点からガイドカーブを作成する方法を説明しました.
2つのスケッチと1つのガイドカーブから,ロフトによって3次元形状を作成する方法を説明しました.
Post Thumbnail by Rob Marquardt