SpacialFiltre get points of clip boundary.

SpacialFiltre get points of clip boundary.

fsztuczny
Advocate Advocate
848 Views
1 Reply
Message 1 of 2

SpacialFiltre get points of clip boundary.

fsztuczny
Advocate
Advocate
I need to replace clipped xrefs to block references, but the block should be clipped identically as the xrefs. I can get points of clip boundary but they are stored in UCS. But this is no problem. Problem is when I try to get points of clipped boundary of COPY of clipped xrefs. These points are located in original clipped xref location, they are not moved. How to transform it to required block reference?
0 Likes
Accepted solutions (1)
849 Views
1 Reply
Reply (1)
Message 2 of 2

fsztuczny
Advocate
Advocate
Accepted solution

I have a solution:

		[CommandMethod( "testClip", CommandFlags.Modal )]
		public void testClip() // This method can have any name
		{
			try
			{
				Document doc = Application.DocumentManager.MdiActiveDocument;
				Database db = doc.Database;
				Editor ed = doc.Editor;
				const string filterDictName = "ACAD_FILTER";
				const string spatialName = "SPATIAL";
				//Wybrać blok
				PromptEntityOptions peo = new PromptEntityOptions( "\nWskaż blok: " );
				peo.AllowNone = true;
				PromptEntityResult per = null;
				do
				{
					per = ed.GetEntity( peo );
					if( per.Status == PromptStatus.OK )
					{
						using( Transaction tr = db.TransactionManager.StartTransaction() )
						{
							BlockTableRecord curSpc = tr.GetObject( db.CurrentSpaceId, OpenMode.ForWrite ) as BlockTableRecord;
							Entity ent = tr.GetObject( per.ObjectId, OpenMode.ForRead ) as Entity;
							if( ent.GetType() == typeof( BlockReference ) )
							{
								//Jest blok. Wyłuskać obwiednię.
								BlockReference blRef = ent as BlockReference;
								if( blRef.ExtensionDictionary != ObjectId.Null )
								{
									DBDictionary extdict = tr.GetObject( blRef.ExtensionDictionary, OpenMode.ForRead ) as DBDictionary;

									if( extdict.Contains( filterDictName ) )
									{
										DBDictionary fDict = tr.GetObject( extdict.GetAt( filterDictName ), OpenMode.ForRead ) as DBDictionary;
										if( fDict.Contains( spatialName ) )
										{
											SpatialFilter sf = tr.GetObject( fDict.GetAt( spatialName ), OpenMode.ForRead ) as SpatialFilter;
											SpatialFilterDefinition sfd = sf.Definition;
											var pts = sfd.GetPoints();
											Matrix3d matBloku = sf.ClipSpaceToWorldCoordinateSystemTransform.PreMultiplyBy( sf.OriginalInverseBlockTransform ).PreMultiplyBy( blRef.BlockTransform );
											Matrix3d invMat = sf.OriginalInverseBlockTransform;
											//Jeśli są dwa punkty, to jest tylko prostokąt. Jeśli więcej, to wielobok.
											Polyline pln = new Polyline();
											if( pts.Count == 2 )
											{
												Point2d pts0 = pts[0];
												Point2d pts1 = pts[1];
												Point2d p0 = RKGeometryczne.punkt3Dna2D( new Point3d( pts0.X, pts0.Y, 0 ).TransformBy( matBloku ) );
												Point2d p1 = RKGeometryczne.punkt3Dna2D( new Point3d( pts1.X, pts0.Y, 0 ).TransformBy( matBloku ) );
												Point2d p2 = RKGeometryczne.punkt3Dna2D( new Point3d( pts1.X, pts1.Y, 0 ).TransformBy( matBloku ) );
												Point2d p3 = RKGeometryczne.punkt3Dna2D( new Point3d( pts0.X, pts1.Y, 0 ).TransformBy( matBloku ) );
												pln.AddVertexAt( pln.NumberOfVertices, p0, 0, 0, 0 );
												pln.AddVertexAt( pln.NumberOfVertices, p1, 0, 0, 0 );
												pln.AddVertexAt( pln.NumberOfVertices, p2, 0, 0, 0 );
												pln.AddVertexAt( pln.NumberOfVertices, p3, 0, 0, 0 );
											}	//if( pts.Count == 2 )
											else
											{
												for( int i = 0; i < pts.Count; i++ )
												{
													Point2d p = RKGeometryczne.punkt3Dna2D( new Point3d( pts[i].X, pts[i].Y, 0 ).TransformBy( matBloku ) );
													pln.AddVertexAt( pln.NumberOfVertices, p, 0, 0, 0 );
												}	//for( int i = 0; i < pts.Count; i++ )
											}	//else if( pts.Count == 2 )
											pln.ColorIndex = 1;
											pln.Closed = true;
											curSpc.AppendEntity( pln );
											tr.AddNewlyCreatedDBObject( pln, true );
											//foreach( var pt in pts )
											//{
											//	ed.WriteMessage( "\nBoundary point at {0}", pt );
											//}
										}	//if( fDict.Contains( spatialName ) )
									}	//if( extdict.Contains( filterDictName ) )
								}	//if( blRef.ExtensionDictionary != ObjectId.Null )
							}	//if( ent.GetType() == typeof( BlockReference ) )
							tr.Commit();
						}	//using( Transaction tr = db.TransactionManager.StartTransaction() )
					}	//if( per.Status == PromptStatus.OK )
				} while( per.Status == PromptStatus.OK );
			}
			catch( System.Exception ex )
			{
				Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage( ex.ToString() );
			}
		}

Most important:

BlockReference blRef = ent as BlockReference;

...

											SpatialFilter sf = tr.GetObject( fDict.GetAt( spatialName ), OpenMode.ForRead ) as SpatialFilter;
											SpatialFilterDefinition sfd = sf.Definition;
											var pts = sfd.GetPoints();
											Matrix3d matBloku = sf.ClipSpaceToWorldCoordinateSystemTransform.PreMultiplyBy( sf.OriginalInverseBlockTransform ).PreMultiplyBy( blRef.BlockTransform );

...

													Point2d p = RKGeometryczne.punkt3Dna2D( new Point3d( pts[i].X, pts[i].Y, 0 ).TransformBy( matBloku ) );
													pln.AddVertexAt( pln.NumberOfVertices, p, 0, 0, 0 );