tpaviot / pythonocc-core

Python package for 3D geometry CAD/BIM/CAM
GNU Lesser General Public License v3.0
1.27k stars 365 forks source link

Node selection using cloud point #1029

Open ferhubsch opened 2 years ago

ferhubsch commented 2 years ago

Hello there! I am trying to find the coordinates of a clicked node using a cloud point. I manage to do that easily when using gp_Pnt objects, but not with cloudPoints. I am using the register_select_callback method which doesn't work in this case, since cloudPoints are not a shape. Unfortunately in my use case I cannot stick with gp_Pnts because I use far too many nodes, so the presentation becomes very slow.

The closest I got was using a AIS_PointCloudOwner which has the method cloud_owner.SelectedPoints() but this yields an object that I could find no use for ('TColStd_HPackedMapOfInteger').

from OCC.Core.gp import gp_Pnt
from OCC.Core.Quantity import Quantity_Color, Quantity_TOC_RGB
from OCC.Core.Graphic3d import Graphic3d_ArrayOfPoints
from OCC.Core.AIS import AIS_PointCloud, AIS_PointCloudOwner
from OCC.Display.SimpleGui import init_display
import numpy as np

display, start_display, add_menu, add_function_to_menu = init_display()

def color_rgb(r, g, b):
    return Quantity_Color(r/255, g/255, b/255, Quantity_TOC_RGB)

def create_point_cloud():
    N=20000
    points = np.random.rand(N,3)
    points3d = Graphic3d_ArrayOfPoints(len(points), True)

    for x,y,z in points:
        points3d.AddVertex(gp_Pnt(x, y, z), color_rgb(255,0,0))

    # then build the point cloud
    pointCloud = AIS_PointCloud()
    pointCloud.SetPoints(points3d)

    return pointCloud

def on_point_click(shapes, *kwargs):
    ais_selection = display.Context.Selection()
    selected_points = cloud_owner.SelectedPoints() # this gives a 'TColStd_HPackedMapOfInteger'
    print(selected_points)
    return

if __name__ == '__main__':

    point_cloud = create_point_cloud()
    cloud_owner = AIS_PointCloudOwner(point_cloud)
    point_cloud.SetOwner(point_cloud)

    display.SetSelectionModeVertex()
    display.register_select_callback(on_point_click)
    display.Context.Display(point_cloud, True)
    display.FitAll()
    start_display()
tpaviot commented 2 years ago

Can you please provide a description of the issue.

ferhubsch commented 2 years ago

Hello Sir! I edited the description and added a piece of code, hopping for any insights on the matter. I thank you for any help, if possible.

zjuzhh commented 1 year ago

Hello sir , I meet the same question. I ues v3d_view to display some cad model(ais_shape) and pointcloud model(ais_pointcloud)succesfully, but when i want to select some points from an ais_pointcloud,it's not the same as selecting TopAbs_Face from the AIS_Slection. The schematic diagram is as follows: test The code I select TopAbs_Face from an ais_shape object is as follows:

   if (!myOccView->getContext()->Selection()->IsEmpty()) {
        const Handle(AIS_Selection) selection = myOccView->getContext()->Selection();
        for (selection->Init(); selection->More(); selection->Next()) {
            Handle(SelectMgr_EntityOwner) entity = selection->Value();
            TopoDS_Shape shape = Handle(StdSelect_BRepOwner)::DownCast(entity)->Shape();

            // Create an explorer to iterate over all faces in the shape.
            TopExp_Explorer explorer_face(shape, TopAbs_FACE);
            ......
            }
    }
 The code I select points from an ais_shape object is as follows:
       Handle(AIS_Selection) selection = myOccView->getContext()->Selection();       
       Handle(AIS_PointCloud) myPointCloud = Handle(AIS_PointCloud)::DownCast(aisObj);
       for (selection->Init(); selection->More(); selection->Next()) {
                Handle(SelectMgr_EntityOwner) entity = selection->Value();
                Handle(AIS_PointCloudOwner) owner = Handle(AIS_PointCloudOwner)::DownCast(entity);
                Handle(TColStd_HPackedMapOfInteger) selectedPoints = owner->SelectedPoints();
                ......
       }
 I don't how to use the selectedPoints(TColStd_HPackedMapOfInteger object) to get every gp_pnt point,could you give me some advice or some sample code?Thanks in advance.