I want to automatize the creation of a Clipping Boundary of an Image (references externes) in Autocad using known coordinates.
I'm able to do it manually using the native function IMAGECLIP in Autocad by drawing a polygon.
It seems the key parameter is ClipBoundary But I'm not able to use it proprely. For your information, the ObjectName of the image is AcDbRasterImage and it has beed add via AddRaster(image_path, insertion_point, 1, 0) (pyautocad). https://help.autodesk.com/view/OARX/2022/ENU/?guid=GUID-D9612F57-7F1F-4CFD-B804-838B826C59FC
I've try this code but it doesn't work :
import comtypes.client
# Connexion à l'application AutoCAD active
acad = comtypes.client.GetActiveObject("AutoCAD.Application")
doc = acad.ActiveDocument
modelspace = doc.ModelSpace
# Appliquer la boundary de clip à l'image raster
def apply_clip_boundary(raster, points):
raster.ClippingEnabled = True # Activer le clipping
# Debugging: Output the clip points to verify the correct format
print("Points to be passed to ClipBoundary:", list(points))
print(raster.ClipBoundary)
# Appliquer la ClipBoundary
raster.ClipBoundary = points # Assurez-vous que les points sont bien formatés
print("Clip boundary applied and enabled.")
print(raster.ClipBoundary)
# Créer les points 2D initiaux (x, y)
points = [
(325100.2407, 7682500.6218),
(325100.6019, 7682500.6218),
(325100.6019, 7682500.3992),
(325100.2407, 7682500.3992),
(325100.2407, 7682500.6218)
]
# Sélectionner un raster par son nom
def get_raster_by_name(name):
for item in modelspace:
if item.ObjectName == "AcDbRasterImage" and item.Name == name:
return item
return None
# Obtenir le raster et appliquer la boundary
raster = get_raster_by_name("photo")
if raster:
apply_clip_boundary(raster, points)
else:
print("Raster not found.")
The result of the script is : no error message, but nothing happens
This is the result when I use : print(raster.ClipBoundary) before passing points
<bound method ClipBoundary of <POINTER(IAcadRasterImage) ptr=0x214be61a5d8 at 214c65509c0>>
and this is the result of the print(raster.ClipBoundary) after passing points:
[(325100.2407, 7682500.6218), (325100.6019, 7682500.6218), (325100.6019, 7682500.3992), (325100.2407, 7682500.3992), (325100.2407, 7682500.6218)]
My conclusion is either I don't pass the good kind of datas (array of points?) or I do not know how to use ClipBoundary.... it seems ClipBoundary is not anymore a method after passing parameters points
While raster.ClipBoundary = points doesn't work, raster.ClippingEnabled = True does work ( I noticed the parameter in Autocad UI changed whenever I pass a parameter True or False for ClippingEnabled)
I'm in nativ WCS (I did not change it). Maybe it's a problem of coordinate system? Does ClipBoundary need points to be passed in local (relativ from the image, from the insert_point of the image? from the boundingbox of the image)? maybe I should use ClipBoundary like a fonction() ?
I also tried to pass directly a polygon, but it doesn't work: from pyautocad import Autocad, APoint, aDouble import comtypes.client from ctypes import c_double
# Connexion à AutoCAD via pyautocad
acad = Autocad(create_if_not_exists=True)
def apply_clip_boundary(raster, points):
# Vérifiez si le raster est bien trouvé avant de continuer
if not raster:
print("Raster not found.")
return
# Créer une polyligne 2D avec les points fournis (pas de Z, donc uniquement X et Y)
polyline_points = aDouble(*[coord for point in points for coord in point]) # Ajouter uniquement X et Y
# Utilisation de AddLightWeightPolyline pour créer une polyline 2D
pl = acad.model.AddLightWeightPolyline(polyline_points)
# Clôturer la polyligne
pl.Closed = True
# Activer la boundary de clip et ajouter la géométrie au raster
raster.ClipBoundary = pl
raster.ClippingEnabled = True
return pl
def get_raster_by_name(name):
# Rechercher le raster par son nom dans le modèle
for item in acad.iter_objects():
if item.ObjectName == "AcDbRasterImage" and item.Name == name:
return item
return None
# Points définissant la boundary de découpe
points = [
(325100.2407, 7682500.6218),
(325100.6019, 7682500.6218),
(325100.6019, 7682500.3992),
(325100.2407, 7682500.3992)
]
# Obtenir le raster et appliquer la boundary
raster = get_raster_by_name("photo")
if raster:
apply_clip_boundary(raster, points)
else:
print("Raster not found.")
Even if I would like to avoid "SendCommand" method, as much as possible. I will accept this solution.
Note: I don't have AutoCAD installed, so I can't do any testing to support my statement(s).
But as the very URL from the question ([AutoDesk.Help]: ClipBoundary Method (ActiveX)) states, ClipBoundary is a method, which means it has to be invoked.
raster.ClipBoundary = points
doesn't make any sense, instead you should:
raster.ClipBoundary(points)