private void MouseClickHandler(Mouse3DPosition mousePosition) { if (!Enabled) { return; } var matchingSketches = new List <int>(); if (mousePosition.MouseDown == false) { var linesEdges = (from line in lines where line != null && line.Shape != null select GeomUtils.ExtractEdge(line.Shape)).ToList(); _document.Revert(); // continue only if we have a drag action if (Math.Abs(mousePosition.Initial2Dx - startX) < 3 && Math.Abs(mousePosition.Initial2Dy - startY) < 3) { return; } bool leftToRight = startX < mousePosition.Initial2Dx ? true : false; if (selectionFace == null) { return; } var sketchNodes = NodeUtils.GetDocumentNodesOfType(_document, FunctionNames.Sketch); // find all sketches that are on the same plane as the selection matchingSketches.AddRange(from sketchNodeIndex in sketchNodes let nb = new NodeBuilder(_document.Root[sketchNodeIndex]) let normal = nb.Dependency[0].TransformedAxis3D where normal.IsParallel(viewPlane.Axis, Precision.Confusion) select sketchNodeIndex); var pointsToShapeMapping = new Dictionary <int, List <int> >(); var shapeToPointMapping = new Dictionary <int, List <int> >(); var functionNames = new List <string> { FunctionNames.Circle, FunctionNames.Ellipse, FunctionNames.LineTwoPoints, FunctionNames.Arc, FunctionNames.Arc3P }; var selectedShapes = new List <int>(); foreach (var index in matchingSketches) { var sketchPoints = NodeUtils.GetSketchPoints(_document.Root[index], _document); // find all shapes and points on the matching sketches foreach (var node in _document.Root.Children) { var builder = new NodeBuilder(node.Value); if (functionNames.Contains(builder.FunctionName)) { var currentSketchNode = AutoGroupLogic.FindSketchNode(node.Value); if (currentSketchNode.Index == index) { if (builder.FunctionName == FunctionNames.Circle) { if (!pointsToShapeMapping.ContainsKey(builder.Dependency[0].Node.Index)) { pointsToShapeMapping.Add(builder.Dependency[0].ReferenceBuilder.Node.Index, new List <int> { builder.Node.Index }); } else { pointsToShapeMapping[builder.Dependency[0].ReferenceBuilder.Node.Index].Add(builder.Node.Index); } shapeToPointMapping.Add(builder.Node.Index, new List <int> { builder.Dependency[0].ReferenceBuilder.Node.Index }); } else { var pointsList = new List <int>(); for (int k = 0; k < builder.Dependency.Count; k++) { if (!pointsToShapeMapping.ContainsKey(builder.Dependency[k].ReferenceBuilder.Node.Index)) { pointsToShapeMapping.Add(builder.Dependency[k].ReferenceBuilder.Node.Index, new List <int> { builder.Node.Index }); } else { pointsToShapeMapping[builder.Dependency[k].ReferenceBuilder.Node.Index].Add(builder.Node.Index); } pointsList.Add(builder.Dependency[k].ReferenceBuilder.Node.Index); } shapeToPointMapping.Add(builder.Node.Index, pointsList); } } var edge = GeomUtils.ExtractEdge(builder.Shape); if (edge != null && !edgeMappings.ContainsKey(builder.Node.Index)) { edgeMappings.Add(builder.Node.Index, edge); } } } var selectedPoints = new List <int>(); // check which points are inside the selection foreach (var point in sketchPoints) { var shapeFace = new NodeBuilder(point).Shape; if (shapeFace == null) { continue; } var common = new BRepAlgoAPICommon(selectionFace, shapeFace); if (common.IsDone) { var commonArea = GeomUtils.GetFaceArea(common.Shape); if (commonArea > 0) { selectedPoints.Add(point.Index); } } _document.Transact(); } // Left->Right - only shapes that are fully inside the selection box are selected if (leftToRight) { foreach (var point in selectedPoints) { if (!pointsToShapeMapping.ContainsKey(point)) { selectedShapes.Add(point); continue; } var shapes = pointsToShapeMapping[point]; foreach (var shape in shapes) { var points = shapeToPointMapping[shape]; var allPointsAreSelected = true; foreach (var pointIndex in points) { if (!selectedPoints.Contains(pointIndex)) { allPointsAreSelected = false; break; } } if (allPointsAreSelected) { selectedShapes.Add(shape); } } } selectedShapes = selectedShapes.Distinct().ToList(); } else { // Right->Left - shapes that are corssed by the selection box are also included in the selection foreach (var point in selectedPoints) { if (pointsToShapeMapping.ContainsKey(point)) { selectedShapes.AddRange(pointsToShapeMapping[point]); } else { selectedShapes.Add(point); } } foreach (var edgeMapping in edgeMappings) { if (!selectedShapes.Contains(edgeMapping.Key)) { foreach (var line in linesEdges) { var intersection = GeomUtils.IntersectionPoints(line, edgeMapping.Value); if (intersection.Count > 0) { selectedShapes.Add(edgeMapping.Key); break; } } } } } } selectedShapes = selectedShapes.Distinct().ToList(); _selectionContainer.BuildSelections(selectedShapes); Inputs[InputNames.UiElementsItem].Send(NotificationNames.RefreshPropertyTabMultipleSelections, _selectionContainer.Entities); _document.Transact(); return; } selectedNodesIndexes.Clear(); startX = mousePosition.Initial2Dx; startY = mousePosition.Initial2Dy; startPoint = mousePosition.Point; var correctedMousePosition = CalculateCorrectCoordinate(mousePosition); _context.MoveTo(correctedMousePosition.Initial2Dx, correctedMousePosition.Initial2Dy, ViewItems.View); if (mousePosition.MouseDown) { if (mousePosition.ShiftDown) { _context.ShiftSelect(true); } else { _context.Select(true); } } // Perform click selection using the corrected coordinate _selectionContainer.BuildSelections(correctedMousePosition); if (_selectionContainer.Entities.Count == 2) { Inputs[InputNames.UiElementsItem].Send(NotificationNames.RefreshPropertyTabTwoSelections, _selectionContainer.Entities); } if (_selectionContainer.Entities.Count == 1) { Inputs[InputNames.UiElementsItem].Send(NotificationNames.SelectNode, _selectionContainer.Entities[0].Node); } }