CAD日記

主にAutoCADのことについて書いているけど、近頃は投資系ネタに注力している。自動売買、仮想通貨、PC関係、プログラミングなど。@caddiary

ソフト開発 DWG

ハッチングの境界データのスプラインをポリラインに分解する方法

投稿日:

dwgにおけるハッチングの表現はややこしくて、boundary(境界)オブジェクトが多階層化している。境界オブジェクトには大きく2つあって、1つの閉じたポリラインか複数のその他図形群かとなる。1つのポリラインであれば何てことはなくて、bulge(ふくらみ)によって途中に円弧があるかもしれないねくらいの話で済むが、その他図形群がタイヘンなことであり、線(Line)か円・円弧(Circle or Arc)か楕円・楕円弧(Ellipe or Ellipe arc)か曲線(Nurbs Curve)かという選択になる。線、円、楕円なんてところはわけないので省略して、曲線の場合のラビリンスから抜け出せたので、以下で詳細に解説しよう。なお、以下はTeigha改めODAによってハッチングオブジェクト内容の境界図形を解析するという話であり、一般性が低いことを先に伝えておく。

境界オブジェクトがその他図形群の場合に現れる曲線タイプのクラスがOdGeNurbCurve2d。OdDbSplineだったらexplodeGeometryでポリラインになるから一発解決なんだけど、OdGeNurbCurve2dってのは何だってこと。NURBS曲線であることは字面からわかる。Bスプライン、ベジェ曲線を一般化したものだそうだ。NURBSが非一様有理Bスプラインであるのに対し、ベジェ曲線は一様非有理Bスプライン。。いや、よくわからんよ。興味あるならWikipediaのNURBSでも読んでくれ。

OdGeNurbCurve2dクラスにはexplode系関数がない。継承元のOdGeCurve2dにexplode関数があったから試してみたが例外エラー発生。explode系関数はOdDbEntityクラスにあるものなんで、OdDbEntityクラスを継承しているOdDbSplineにする必要がありそうなことは薄々わかっていた。そこで難関だったのはNURBS系情報の受け渡し。

OdGeCurve2d::getDefinitionDataでGETして、OdDbSpline::setNurbsDataでSETする。この関数の引数が微妙に違っていることに苦労した。コードを以下に貼りける。ちょっとした違いがある。

// OdGeNurbCurve2d* pNurbをOdDbSpline pDstに変換する処理
bool closed = false;
DPOINT pnt1 = { pNurb->startPoint().x, pNurb->startPoint().y };
DPOINT pnt2 = { pNurb->endPoint().x, pNurb->endPoint().y };
double dist = GeoGetDis(&pnt1, &pnt2);
if (dist <= ZERO * 100)  // つながってる
	closed = true;
int degree = 0;
bool rational = false, periodic = false;
OdGeKnotVector knots;
OdGePoint2dArray controlPoints;
OdGeDoubleArray weights;
pNurb->getDefinitionData(degree, rational, periodic, knots, controlPoints, weights);

OdDbSplinePtr pDst = OdDbSpline::createObject();
double controlPtTol = 0, knotTol = 0;
OdGePoint3dArray controlPoints3d;
for (int j = 0; j < (int)controlPoints.size(); j++)
{
	OdGePoint3d pnt(controlPoints[j].x, controlPoints[j].y, 0);
	controlPoints3d.append(pnt);
}
OdGeDoubleArray knots2;
for (int j = 0; j < knots.length(); j++)
{
	const double* pPtr = knots.getPtr();
	knots2.append(pPtr[j]);
}
pDst->setNurbsData(degree, rational, closed, periodic, controlPoints3d, knots2, weights, controlPtTol, knotTol);

OdDbSplineに変換できたからexplodeGeometoryすればいいわけだが、その結果現れたのがOdDb2dPolylineというのがミソ。OdDb2dPolylineにはふくらみがあるのは当然として、なんとスプラインが含まれていることもある。元がNURB曲線で、スプラインにして、ポリラインにして、分解したらスプラインって。。いやいや、スプラインを分解したポリラインにスプラインなんて含まれているわけないと断定。よって、以下の通り、頂点(Vertex)情報だけ拾い出して、DPOINTの配列にAddした。

CArray<DPOINT, DPOINT> ary;
OdRxObjectPtrArray oary;
OdResult err = pDst->explodeGeometry(oary);
if (err != eOk)
	return FALSE;
for (UINT k = 0; k < oary.size(); k++)
{
	OdDbEntityPtr pExp = OdDbEntity::cast(oary.getAt(k));
	int type = ElmGetType(pExp.get());
	if (type == _ENT_PLINE2D)
	{
		OdDb2dPolylinePtr pPoly = pExp;
		OdDbObjectIteratorPtr pIter = pPoly->vertexIterator();
		for (; !pIter->done(); pIter->step())
		{
			OdDb2dVertexPtr pVs = pIter->entity();
			if (!pVs.get())
				continue;
			OdGePoint3d pos = pVs->position();
			DPOINT pnt = { pos.x, pos.y };
			ary.Add(pnt);
		}
		if (pPoly->isClosed())
			ary.Add(ary.GetAt(0));
	}
}

サクッとかいた閉じたスプラインに対して上記処理を行ったところ、52個の頂点だったのでそこそこの精度でポリライン変換できたことになる。もちろん、ふくらみもスプラインも現れなかった。
ポリラインの点列ができれば、ライトウェイトポリライン(OdDbPolyline)として仕立てて、いろんな編集ができるってもの。

こんなことができて何がうれしいかって?塗りつぶしハッチングをビューポートでぶった切った状態をモデル空間の図形に変換できるようになる。塗りつぶしでないハッチングであれば分解して線の集まりにしてまえば見た目を維持できるが、塗りつぶしとなればハッチング要素として維持しなくてはならず、輪郭オブジェクトとしてのOdGeNurbCurve2dがクリッピングできなかったという話。上記で頂点列にすることができたから、クリッピング処理に流すことができるようになった。そして、塗りつぶしハッチングの境界データのスプライン部分をポリラインに分解してクリッピングができたという次第。

ハッチングの境界データが閉じてないとハッチングとして成り立たないから閉じてやったり、境界データを普通の図形に変換してやったり、境界データをクリッピングするなんてことは、AutoCADや互換CADのアドオンツールとして成り立ちそうな気がしてきた。切り出して、単独ツールとしてみるのもよいだろう。

-ソフト開発, DWG

執筆者:


comment

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

no image

iTextSharpによるPDFファイルのページ分割

iTextSharpはフリーのPDF関連コンポーネントであり、いろんなことができるのは知っていた。ドットNET、つまりC#かVB使いであれば、けっこう簡単にPDFを操ることができるのだが、あいにくおい …

no image

Drawing

DWG=drawingの略称。 海外CAD事情 566号「商標ウオッチ:“俺の”DWGを返せ」を読んで、初めて知った。 drawingと言えば、図面。 こんな単純な意味合いだとは知らなかった。 CAD …

no image

DWGビューア

ペーパーモデル化ツールにDWGビューアが添付されていることは、 あまり知られていない。 インストールしたフォルダ内のView.exeを叩けば、起動できる。 例)C:¥Program Files¥PMt …

no image

DXFハンドブック 第2版

10年振りの改定版が出ているのに気付いたので早速購入。 なかなか売ってないかなと思ったら、会社近くのくまざわ書店にて発見。 価格は高いがその価値あり。 DXFハンドブック 第2版 作者: 落合 重紀 …

zipcopy~圧縮してコピー~ができたのでアップしておく

【zipcopyの概要】 大きなファイルやフォルダをネットワーク越しにコピーする際、圧縮してからコピーすることで、ネットワークの帯域を少しで使わないようにすることを目的とする。以下3つの手順を自動的に …