/// <summary> /// Конструктор глушителя /// </summary> /// <param name="figureParameters">Parameters of muffler</param> /// <param name="kompasApp">Kompas application specimen</param> /// <param name="basePlane">Base plane of muffler, by default is null</param> public Muffler(KompasApplication kompasApp, MufflerParameters figureParameters, ksEntity basePlane = null) { if (kompasApp == null || figureParameters.Document3DPart == null || figureParameters.BasePlanePoint.LastErrorCode != ErrorCodes.OK || !(figureParameters.BasePlaneAxis == Obj3dType.o3d_planeXOY || figureParameters.BasePlaneAxis == Obj3dType.o3d_planeXOZ || figureParameters.BasePlaneAxis == Obj3dType.o3d_planeYOZ) || !DoubleValidator.Validate(figureParameters.BasePlanePoint.X) || !DoubleValidator.Validate(figureParameters.BasePlanePoint.Y)) { LastErrorCode = ErrorCodes.ArgumentNull; return; } if (!(figureParameters.Direction == Direction_Type.dtNormal || figureParameters.Direction == Direction_Type.dtReverse)) { LastErrorCode = ErrorCodes.ArgumentInvalid; return; } _kompasApp = kompasApp; _figureParameters = figureParameters; Extrusion = CreateMuffler(figureParameters, basePlane); if (Extrusion == null) { return; } }
/// <summary> /// Create rounded chamfer in regular polygon sketch by base sketch, /// regular polygon parameters and base plane coordinates in plane /// </summary> /// <param name="doc3D">Kompas document 3D</param> /// <param name="doc3DPart">Kompas document 3D part with detail</param> /// <param name="regPolySketch">Sketch of regular polygon</param> /// <param name="regPolyParam">An object with parameters of regular polygon</param> /// <param name="basePlanePoint">Base plane point of regular polygon</param> /// <param name="directionType">Direction type</param> /// <returns>Entity of rounded chamfer or null in case of error</returns> public RoundedChamfer(KompasApplication kompasApp, RoundedChamferParameters figureParameters) { if (kompasApp == null || figureParameters.Document3DPart == null || figureParameters.RegularPolygonSketch == null || figureParameters.RegularPolygonParameters == null ) { LastErrorCode = ErrorCodes.ArgumentNull; return; } // KompasApplication kompasApp, ksPart doc3DPart, ksEntity regPolySketch, RegularPolygonParameter regPolyParam, KompasPoint2D basePlanePoint, Direction_Type directionType _figureParameters = figureParameters; _kompasApp = kompasApp; if (!DoubleValidator.Validate(_figureParameters.BasePlanePoint.X) || !DoubleValidator.Validate(_figureParameters.BasePlanePoint.Y) ) { LastErrorCode = ErrorCodes.DoubleValueValidationError; return; } }
/// <summary> /// Параметр вращения по граням вращения (начало и конец), /// точке расположения вращения, размеру диаметра и шагу вращения /// </summary> /// <param name="parameters">Parameters of spin</param> public Spin(SpinParameters parameters) { if (parameters.BeginSpinFace == null || parameters.EndSpinFace == null || parameters.SpinLocationPoint.LastErrorCode != ErrorCodes.OK || parameters.DiameterSize == default(double) || !DoubleValidator.Validate(parameters.DiameterSize) || parameters.SpinStep == default(double) || !DoubleValidator.Validate(parameters.SpinStep) ) { LastErrorCode = ErrorCodes.ArgumentNull; return; } if (parameters.DiameterSize <= default(double) || !DoubleValidator.Validate(parameters.DiameterSize) || !DoubleValidator.Validate(parameters.SpinLocationPoint.X) || !DoubleValidator.Validate(parameters.SpinLocationPoint.Y) ) { LastErrorCode = ErrorCodes.DoubleValueValidationError; return; } if (!CreateSpin(parameters)) { return; } }
private IEnumerable <string> ValidateUnitGrams(string grams, [CallerMemberName] string propertyName = "") { var validator = new DoubleValidator(minimum: MinimumGrams); var validationResults = validator.Validate(grams); SetValidationResults(validationResults, propertyName); return(validationResults); }
private IEnumerable <string> ValidateMacroGrams(string grams, [CallerMemberName] string propertyName = "") { var validator = new DoubleValidator(minimum: FoodUnitConstants.MinimumAllowedMacroGrams); var validationResults = validator.Validate(grams); SetValidationResults(validationResults, propertyName); return(validationResults); }
/// <summary> /// Kompas 2D Point /// </summary> /// <param name="xc">X coordinate</param> /// <param name="yc">Y coordinate</param> public KompasPoint2D(double xc, double yc) { X = default(double); Y = default(double); LastErrorCode = ErrorCodes.OK; if (!DoubleValidator.Validate(xc) || !DoubleValidator.Validate(yc) ) { LastErrorCode = ErrorCodes.ArgumentInvalid; return; } X = xc; Y = yc; }
/// <summary> /// Get cylinder base plane indexes by indexes of faces of cylinder inside detail faces collection /// </summary> /// ksFaceDefinition.IsCylinder () определяет, является ли грань цилиндрической или нет, /// это кажется нелогичным, но в любом случае: базовые плоскости НЕ являются цилиндрическими, /// они просто плоские круги /// <param name="_doc3DPart">Document 3D part, represents detail</param> /// <param name="startIndex">Start index of faces in faces collection</param> /// <param name="endIndex">End index of faces in faces collection</param> /// <param name="outFirstIndex">First base plane index</param> /// <param name="outSecondIndex">Second base plane index</param> public static void GetCylinderBasePlaneIndexes(ksPart _doc3DPart, int startIndex, int endIndex, out int outFirstIndex, out int outSecondIndex) { /* функция getCylinderBasePlane работает только, если базовая плоскость больше размером, чем получаемая */ var faceCollection = (ksEntityCollection)_doc3DPart.EntityCollection((short)Obj3dType.o3d_face); if (faceCollection == null || !DoubleValidator.Validate(startIndex) || !DoubleValidator.Validate(endIndex) ) { outFirstIndex = outSecondIndex = -1; return; } bool isFirstIndexSet = false; int firstIndex = -1; int secondIndex = -1; for (int i = startIndex - 1; i < endIndex; i++) { uint ST_MIX_SM = 0x0; //площадь в сантиметрах var entity = (ksEntity)faceCollection.GetByIndex(i); var def = (ksFaceDefinition)entity.GetDefinition(); var area = Math.Round(def.GetArea(ST_MIX_SM), 10); //округлить до 10 чисел // Если грань не является цилиндрической, и если она не является базовой гранью if (!def.IsCylinder() && isFirstIndexSet == false) { isFirstIndexSet = true; firstIndex = i; } else if (!def.IsCylinder() && isFirstIndexSet == true) { secondIndex = i; } } outFirstIndex = firstIndex; outSecondIndex = secondIndex; return; }
/// <summary> /// Получить индексы базовой плоскости цилиндра по индексам граней цилиндра /// внутри коллекции граней деталей /// </summary> /// <param name="_doc3DPart">Document 3D part, представляет деталь</param> /// <param name="startIndex">Start index of faces in faces collection</param> /// <param name="endIndex">End index of faces in faces collection</param> /// <param name="outFirstIndex">First base plane index</param> /// <param name="outSecondIndex">Second base plane index</param> public static void GetCylinderBasePlaneIndexes(ksPart _doc3DPart, int startIndex, int endIndex, out int outFirstIndex, out int outSecondIndex) { var faceCollection = (ksEntityCollection)_doc3DPart.EntityCollection( (short)Obj3dType.o3d_face); if (faceCollection == null || !DoubleValidator.Validate(startIndex) || !DoubleValidator.Validate(endIndex) ) { outFirstIndex = outSecondIndex = -1; return; } bool isFirstIndexSet = false; int firstIndex = -1; int secondIndex = -1; for (int i = startIndex - 1; i < endIndex; i++) { uint ST_MIX_SM = 0x0; var entity = (ksEntity)faceCollection.GetByIndex(i); var def = (ksFaceDefinition)entity.GetDefinition(); var area = Math.Round(def.GetArea(ST_MIX_SM), 10); if (!def.IsCylinder() && isFirstIndexSet == false) { isFirstIndexSet = true; firstIndex = i; } else if (!def.IsCylinder() && isFirstIndexSet == true) { secondIndex = i; } } outFirstIndex = firstIndex; outSecondIndex = secondIndex; return; }
/// <summary> /// Get cylinder base plane indexes by indexes of faces of cylinder inside detail faces collection /// </summary> /// ksFaceDefinition.IsCylinder() defines is face cylindric or not, /// it seems to be unlogical, but in any case: base planes are NOT cylindric, /// they are just plane circles /// <param name="_doc3DPart">Document 3D part, represents detail</param> /// <param name="startIndex">Start index of faces in faces collection</param> /// <param name="endIndex">End index of faces in faces collection</param> /// <param name="outFirstIndex">First base plane index</param> /// <param name="outSecondIndex">Second base plane index</param> public static void GetCylinderBasePlaneIndexes(ksPart _doc3DPart, int startIndex, int endIndex, out int outFirstIndex, out int outSecondIndex) { /* TODO: функция getCylinderBasePlane работает только, если базовая плоскость больше размером, чем получаемая */ var faceCollection = (ksEntityCollection)_doc3DPart.EntityCollection((short)Obj3dType.o3d_face); if (faceCollection == null || !DoubleValidator.Validate(startIndex) || !DoubleValidator.Validate(endIndex) ) { outFirstIndex = outSecondIndex = -1; return; } bool isFirstIndexSet = false; int firstIndex = -1; int secondIndex = -1; for (int i = startIndex - 1; i < endIndex; i++) { uint ST_MIX_SM = 0x0; // area in santimeters var entity = (ksEntity)faceCollection.GetByIndex(i); var def = (ksFaceDefinition)entity.GetDefinition(); var area = Math.Round(def.GetArea(ST_MIX_SM), 10); // round to 10 numbers // If face isn't cylindric and if it is not base face (see xml-comment to this function) if (!def.IsCylinder() && isFirstIndexSet == false) { isFirstIndexSet = true; firstIndex = i; } else if (!def.IsCylinder() && isFirstIndexSet == true) { secondIndex = i; } } outFirstIndex = firstIndex; outSecondIndex = secondIndex; return; }
/// <summary> /// Get regular polygon param /// </summary> /// <param name="_kompas">Kompas object</param> /// <param name="anglesCount">Angles count</param> /// <param name="inscribedCircleRadius">Inscribed circle radius</param> /// <param name="point2D">Two-dimensional point of figure base</param> public RegularPolygonParameter(KompasApplication kompasApp, int anglesCount, double inscribedCircleRadius, KompasPoint2D point2D) { if (kompasApp == null) { LastErrorCode = ErrorCodes.ArgumentNull; return; } // Angles amount must be from 3 to 12 if (anglesCount <= 2 || anglesCount >= 13 || !DoubleValidator.Validate(anglesCount) || inscribedCircleRadius <= 0.0 || !DoubleValidator.Validate(inscribedCircleRadius) || !DoubleValidator.Validate(point2D.X) || !DoubleValidator.Validate(point2D.Y) ) { LastErrorCode = ErrorCodes.ArgumentInvalid; return; } // Regular polygon is base of hat ksRegularPolygonParam polyParam; polyParam = kompasApp.KompasObject.GetParamStruct((short)StructType2DEnum.ko_RegularPolygonParam); if (polyParam == null) { LastErrorCode = ErrorCodes.EntityDefinitionNull; return; } polyParam.count = anglesCount; // Count of angles polyParam.ang = 0; // Radius-vector angle from center to first top polyParam.describe = true; // The polygon is DEscribed polyParam.radius = inscribedCircleRadius; // INscribed circle radius, / W3 / polyParam.style = 1; // Line style polyParam.xc = point2D.X; polyParam.yc = point2D.Y; // Plane coordinates FigureParam = polyParam; }
/// <summary> /// Get regular polygon param /// </summary> /// <param name="_kompas">Kompas object</param> /// <param name="anglesCount">Angles count</param> /// <param name="inscribedCircleRadius">Inscribed circle radius</param> /// <param name="point2D">Two-dimensional point of figure base</param> public RegularPolygonParameter(KompasApplication kompasApp, int anglesCount, double inscribedCircleRadius, KompasPoint2D point2D) { if (kompasApp == null) { LastErrorCode = ErrorCodes.ArgumentNull; return; } if (anglesCount <= 2 || anglesCount >= 13 || !DoubleValidator.Validate(anglesCount) || inscribedCircleRadius <= 0.0 || !DoubleValidator.Validate(inscribedCircleRadius) || !DoubleValidator.Validate(point2D.X) || !DoubleValidator.Validate(point2D.Y) ) { LastErrorCode = ErrorCodes.ArgumentInvalid; return; } ksRegularPolygonParam polyParam; polyParam = kompasApp.KompasObject.GetParamStruct( (short)StructType2DEnum.ko_RegularPolygonParam); if (polyParam == null) { LastErrorCode = ErrorCodes.EntityDefinitionNull; return; } polyParam.count = anglesCount; polyParam.ang = 0; polyParam.describe = true; polyParam.radius = inscribedCircleRadius; polyParam.style = 1; polyParam.xc = point2D.X; polyParam.yc = point2D.Y; FigureParam = polyParam; }
/// <summary> /// Set rectangle param /// </summary> /// <param name="kompas">KompasObject</param> /// <param name="width">Rectangle width</param> /// <param name="height">Rectangle height</param> /// <param name="point2D">2D point of rectangle position on sketch</param> public RectangleParameter(KompasApplication kompasApp, double width, double height, KompasPoint2D point2D) { if (kompasApp == null || point2D.LastErrorCode != ErrorCodes.OK ) { LastErrorCode = ErrorCodes.ArgumentNull; return; } if (width <= 0.0 || !DoubleValidator.Validate(width) || height <= 0.0 || !DoubleValidator.Validate(height) || !DoubleValidator.Validate(point2D.X) || !DoubleValidator.Validate(point2D.Y) ) { LastErrorCode = ErrorCodes.ArgumentInvalid; return; } ksRectangleParam rectangleParam; rectangleParam = kompasApp.KompasObject.GetParamStruct( (short)StructType2DEnum.ko_RectangleParam); rectangleParam.width = width; rectangleParam.height = height; rectangleParam.ang = 0; rectangleParam.style = 1; rectangleParam.x = point2D.X; rectangleParam.y = point2D.Y; if (rectangleParam == null) { LastErrorCode = ErrorCodes.EntityDefinitionNull; return; } FigureParam = rectangleParam; }
/// <summary> /// Выдавливание по направлению, глубине и выдавливаемому объекту /// </summary> /// <param name="doc3DPart">Kompas document 3D part</param> /// <param name="extrusionType">Extrusion type</param> /// <param name="extrudableEntity">Extrudable entity</param> /// <param name="direction">Extrusion direction</param> /// <param name="depth">Extrusion depth</param> public KompasExtrusion(KompasExtrusionParameters parameters, ExtrusionType extrusionType) { if (parameters.Document3DPart == null) { LastErrorCode = ErrorCodes.KompasFigureNotSet; return; } // Extrusion entity var entity = (ksEntity)parameters.Document3DPart.NewEntity((short)parameters.ExtrusionType); if (entity == null) { LastErrorCode = ErrorCodes.ExtrusionEntityCreationError; return; } // ExtrudABLE entity isn't using ONLY in base loft if (parameters.ExtrusionType != Obj3dType.o3d_baseLoft) { if (parameters.ExtrudableEntity == null) { LastErrorCode = ErrorCodes.ExtrudableEntityNotSet; return; } } // Получение направление выдавливания bool normalDirection = true; if (extrusionType == ExtrusionType.ByEntity) { if (parameters.Direction == Direction_Type.dtNormal) { normalDirection = true; } else if (parameters.Direction == Direction_Type.dtReverse) { normalDirection = false; } else { LastErrorCode = ErrorCodes.ExtrusionDirectionNotSupported; return; } // Глубина не должна быть равна нулю if (parameters.Depth == default(double) || !DoubleValidator.Validate(parameters.Depth)) { LastErrorCode = ErrorCodes.ArgumentInvalid; return; } } // Entity faces count before extrusion var faceCollection = (ksEntityCollection)parameters.Document3DPart.EntityCollection((short)Obj3dType.o3d_face); _facesCountBeforeExtrusion = faceCollection.GetCount(); switch (extrusionType) { case ExtrusionType.ByEntity: if (!CreateExtrusionByDirection(entity, parameters, normalDirection)) { return; } break; case ExtrusionType.BySketchesCollection: if (!CreateExtrusionBySketchCollection(entity, parameters)) { return; } break; } _doc3DPart = parameters.Document3DPart; // Get faces count after extrusion faceCollection.refresh(); _facesCountAfterExtrusion = faceCollection.GetCount(); if (_facesCountAfterExtrusion == _facesCountBeforeExtrusion) { LastErrorCode = ErrorCodes.ExtrusionFacesCountWrong; return; } }
/// <summary> /// Return face which is parallel to base face /// </summary> /// This algorithm uses areas of faces collection /// in diapason from start index to end index. /// The essence of the algorithm is that any extruded figure /// has parralel top and bottom planes and sides planes, /// and areas of these planes are equal as side planes! /// But all these planes are sorted randomly. /// If we add any figure to bottom plane /// (i.e. create sketch and extrude him on bottom plane) /// then area of bottom plane decreases /// and we can exactly say which index belongs to each parralel plane! /// <param name="_doc3DPart">Kompas part of 3D document</param> /// <param name="startIndex">Face collection start index</param> /// <param name="endIndex">Face collection end index</param> /// <param name="outFirstIndex">First base plane index in faces collection</param> /// <param name="outSecondIndex">Second base plane index in faces collection</param> public static void GetRegPolyBasePlanesIndexes(ksPart _doc3DPart, int startIndex, int endIndex, out int outFirstIndex, out int outSecondIndex) { /* TODO: эта функция работает только с многоугольниками с количеством граней строго больше 4 */ // Collection of entities in all figure var faceCollection = (ksEntityCollection)_doc3DPart.EntityCollection((short)Obj3dType.o3d_face); List <double> initList = new List <double>(); List <double> unroundedList = new List <double>(); List <double> uniqList = new List <double>(); List <double> notUniqList = new List <double>(); if (faceCollection == null || !DoubleValidator.Validate(startIndex) || !DoubleValidator.Validate(endIndex) ) { outFirstIndex = outSecondIndex = -1; return; } int firstIndex = startIndex - 1; int secondIndex = startIndex - 1; // Set figure faces areas list with all areas for (int i = startIndex - 1; i < endIndex; i++) { uint ST_MIX_SM = 0x0; // this is similar to "area in santimeters" definition in API var entity = (ksEntity)faceCollection.GetByIndex(i); var def = (ksFaceDefinition)entity.GetDefinition(); // Get unrounded area of plane var area = def.GetArea(ST_MIX_SM); unroundedList.Add(area); } // Get minimal epsilon for all unrounded areas (see comment to this function) var minimalEpsilon = GetMinimalEspilonOfAreas(unroundedList); // Set init list with rounded values for (int i = 0, length = unroundedList.Count; i < length; i++) { initList.Add(Math.Round(unroundedList[i], minimalEpsilon)); } // Get unique areas in this list for (int i = 0, length = initList.Count; i < length; i++) { // If value is not set neither in unique nor in non-unique list -- // -- then set him to unique list if (!uniqList.Contains(initList[i])) { if (!notUniqList.Contains(initList[i])) { uniqList.Add(initList[i]); } } else { // Else if he already set in unique list -- // -- delete from this list and set him to not-unique list, but only once uniqList.Remove(initList[i]); notUniqList.Add(initList[i]); } } // Check this 2 indexes for adjacency with base face of figure if (uniqList.Count == 2) { firstIndex += initList.IndexOf(uniqList[0]); secondIndex += initList.IndexOf(uniqList[1]); } // Else if main base face area is higher than parallel base face area // -- then return only first index else if (uniqList.Count == 1) { firstIndex += initList.IndexOf(uniqList[0]); secondIndex = -1; } // Else if parallel faces doesn't have the same area -- // -- then get value which repeat twice in array else if (uniqList.Count == 0) { bool getFirstElement = false; for (int i = 0, count = initList.Count; i < count; i++) { bool isTwoElements = (GetElementCountInList(initList, initList[i]) == 2); if ((isTwoElements == true) && (getFirstElement == false)) { firstIndex += i; getFirstElement = true; } else if ((isTwoElements == true) && (getFirstElement == true)) { secondIndex += i; break; } } } // Else try to do facepalm and exit immediately else { firstIndex = secondIndex = -1; } outFirstIndex = firstIndex; outSecondIndex = secondIndex; }
/// <summary> /// Вернуть грань, параллельную базовой грани /// </summary> /// Этот алгоритм использует области сбора граней в диапазоне /// от начального индекса до конечного индекса. /// <param name="_doc3DPart">Kompas part of 3D document</param> /// <param name="startIndex">Face collection start index</param> /// <param name="endIndex">Face collection end index</param> /// <param name="outFirstIndex">First base plane index in faces collection</param> /// <param name="outSecondIndex">Second base plane index in faces collection</param> public static void GetRegPolyBasePlanesIndexes(ksPart _doc3DPart, int startIndex, int endIndex, out int outFirstIndex, out int outSecondIndex) { var faceCollection = (ksEntityCollection)_doc3DPart.EntityCollection( (short)Obj3dType.o3d_face); List <double> initList = new List <double>(); List <double> unroundedList = new List <double>(); List <double> uniqList = new List <double>(); List <double> notUniqList = new List <double>(); if (faceCollection == null || !DoubleValidator.Validate(startIndex) || !DoubleValidator.Validate(endIndex) ) { outFirstIndex = outSecondIndex = -1; return; } int firstIndex = startIndex - 1; int secondIndex = startIndex - 1; for (int i = startIndex - 1; i < endIndex; i++) { uint ST_MIX_SM = 0x0; var entity = (ksEntity)faceCollection.GetByIndex(i); var def = (ksFaceDefinition)entity.GetDefinition(); var area = def.GetArea(ST_MIX_SM); unroundedList.Add(area); } var minimalEpsilon = GetMinimalEspilonOfAreas(unroundedList); for (int i = 0, length = unroundedList.Count; i < length; i++) { initList.Add(Math.Round(unroundedList[i], minimalEpsilon)); } for (int i = 0, length = initList.Count; i < length; i++) { if (!uniqList.Contains(initList[i])) { if (!notUniqList.Contains(initList[i])) { uniqList.Add(initList[i]); } } else { uniqList.Remove(initList[i]); notUniqList.Add(initList[i]); } } if (uniqList.Count == 2) { firstIndex += initList.IndexOf(uniqList[0]); secondIndex += initList.IndexOf(uniqList[1]); } else if (uniqList.Count == 1) { firstIndex += initList.IndexOf(uniqList[0]); secondIndex = -1; } else if (uniqList.Count == 0) { bool getFirstElement = false; for (int i = 0, count = initList.Count; i < count; i++) { bool isTwoElements = (GetElementCountInList(initList, initList[i]) == 2); if ((isTwoElements == true) && (getFirstElement == false)) { firstIndex += i; getFirstElement = true; } else if ((isTwoElements == true) && (getFirstElement == true)) { secondIndex += i; break; } } } else { firstIndex = secondIndex = -1; } outFirstIndex = firstIndex; outSecondIndex = secondIndex; }
/// <summary> /// Create thread of base of screw /// </summary> /// <returns>true if operation successful; false in case of error</returns> private bool CreateThread(ksEntity[] carvingEntities) { // 1.5 Screw base thread spin // Spin step by russian GOST is equal to 0.037 (i.e. 3.7%) of spin height var spinParameters = new SpinParameters(); spinParameters.Document3DPart = _kompasApp.ScrewPart; spinParameters.BeginSpinFace = carvingEntities[1]; spinParameters.EndSpinFace = carvingEntities[0]; spinParameters.SpinLocationPoint = new KompasPoint2D(0, 0); spinParameters.DiameterSize = _kompasApp.Parameters[0] * 0.7; // 0.7 W3 spinParameters.SpinStep = _kompasApp.Parameters[3] * 0.037; // 0.037 W2 var screwThreadSpin = new Spin(spinParameters); if (screwThreadSpin.LastErrorCode != ErrorCodes.OK) { LastErrorCode = screwThreadSpin.LastErrorCode; return(false); } ThreadStep = screwThreadSpin.SpinStep; if (!DoubleValidator.Validate(ThreadStep)) { LastErrorCode = ErrorCodes.DoubleValueValidationError; return(false); } // 1.6 Screw base thread sketch var screwThreadSketch = new KompasSketch(_kompasApp.ScrewPart, Obj3dType.o3d_planeXOZ); if (screwThreadSketch.LastErrorCode != ErrorCodes.OK) { LastErrorCode = screwThreadSketch.LastErrorCode; return(false); } var screwThreadEdit = screwThreadSketch.BeginEntityEdit(); if (screwThreadEdit == null) { LastErrorCode = screwThreadSketch.LastErrorCode; return(false); } var step = screwThreadSpin.SpinStep; // W1 + W2 + 3 thread steps - 0.86 * W3 (because part with 0.16 * W3 is in coordinates which are less than zero of XOZ) var endX = _kompasApp.Parameters[2] + _kompasApp.Parameters[3] + _kompasApp.Parameters[4] * 0.86; var startY = -(_kompasApp.Parameters[0] * 0.7 / 2.0); // 0.7 * W3 var endY = -(3.0 / 4.0 * _kompasApp.Parameters[0] * 0.7) / 2.0; // 0.7 * W3 on end of base // Draw triangle: the base of thread. screwThreadEdit.ksLineSeg(endX - step, endY, endX, endY, 1); screwThreadEdit.ksLineSeg(endX, endY, endX - step / 2.0, startY, 1); screwThreadEdit.ksLineSeg(endX - step / 2.0, startY, endX - step, endY, 1); screwThreadSketch.EndEntityEdit(); // 1.7 Screw base thread extrusion var spinCollection = (ksEntityCollection)_kompasApp.ScrewPart.EntityCollection((short)Obj3dType.o3d_cylindricSpiral); if (spinCollection == null) { LastErrorCode = ErrorCodes.EntityCollectionCreateError; return(false); } spinCollection.Clear(); spinCollection.Add(screwThreadSpin.Entity); spinCollection.refresh(); if (spinCollection.GetCount() != 1) { LastErrorCode = ErrorCodes.EntityCollectionWrong; } var extrusionParameters = new KompasExtrusionParameters(_kompasApp.ScrewPart, Obj3dType.o3d_baseEvolution, screwThreadSketch.Entity, spinCollection); var screwThreadExtrusion = new KompasExtrusion(extrusionParameters, ExtrusionType.BySketchesCollection); if (screwThreadExtrusion.LastErrorCode != ErrorCodes.OK) { LastErrorCode = ErrorCodes.EntityCreateError; return(false); } return(true); }
/// <summary> /// Create nut /// </summary> /// <returns>true if operation successful, false in case of error</returns> public bool CreateDetail() { // Base point of nut in three-dimensional coordinate system var nutBasePoint = new KompasPoint3D(0.0, Math.Abs(_kompasApp.Parameters[0]), Math.Abs(_kompasApp.Parameters[0])); // / nut placement / // Depth of cylinder which sets base plane // Nut base point is (0;0) in YOZ after nut base plane creation var regPolyParam = new RegularPolygonParameter(_kompasApp, 6, _kompasApp.Parameters[0] / 2.0, new KompasPoint2D(0.0, 0.0)); if (regPolyParam.LastErrorCode != ErrorCodes.OK) { LastErrorCode = regPolyParam.LastErrorCode; return(false); } // Base plane cylinder depth is W1 + W2 + H + 0.1*W1*W2 var basePlaneCylinderDepth = _kompasApp.Parameters[2] + _kompasApp.Parameters[3] + _kompasApp.Parameters[4] + (_kompasApp.Parameters[2] + _kompasApp.Parameters[3]) * 0.1; if (!DoubleValidator.Validate(basePlaneCylinderDepth)) { LastErrorCode = ErrorCodes.DoubleValueValidationError; return(false); } // 1. Create nut base plane cylinder (base plane is plane in three-dimensional coordinate system, not an entity!) var nutBasePlane = CreateNutBasePlaneCylinder(nutBasePoint, basePlaneCylinderDepth); if (nutBasePlane == null) { LastErrorCode = ErrorCodes.ArgumentNull; return(false); } // Nut base point is (0;0) in YOZ after nut base plane creation nutBasePoint.Y = 0.0; nutBasePoint.Z = 0.0; // 2. Create nut base var nutBaseEntities = CreateNutBase(nutBasePlane, nutBasePoint, regPolyParam); if (nutBaseEntities == null || nutBaseEntities[0] == null || nutBaseEntities[1] == null ) { return(false); } // 3. Delete nut base plane cylinder if (!DeleteNutBasePlaneCylinder(nutBasePlane, basePlaneCylinderDepth)) { return(false); } // 4. Create nut chamfer entities var chamferEntities = CreateNutChamferEntities(nutBasePoint, regPolyParam, nutBaseEntities); if (chamferEntities == null || chamferEntities[0] == null || chamferEntities[1] == null ) { return(false); } // 5. Create nut base cut if (!CreateBaseCut(chamferEntities, nutBasePoint)) { return(false); } // 6. Create nut thread if (!CreateNutThread(chamferEntities, nutBasePoint, basePlaneCylinderDepth)) { return(false); } return(true); }
/// <summary> /// Выдавливание по направлению, глубине и выдавливаемому объекту /// </summary> /// <param name="doc3DPart">Kompas document 3D part</param> /// <param name="extrusionType">Extrusion type</param> /// <param name="extrudableEntity">Extrudable entity</param> /// <param name="direction">Extrusion direction</param> /// <param name="depth">Extrusion depth</param> public KompasExtrusion(KompasExtrusionParameters parameters, ExtrusionType extrusionType) { if (parameters.Document3DPart == null) { LastErrorCode = ErrorCodes.KompasFigureNotSet; return; } var entity = (ksEntity)parameters.Document3DPart.NewEntity( (short)parameters.ExtrusionType); if (entity == null) { LastErrorCode = ErrorCodes.ExtrusionEntityCreationError; return; } if (parameters.ExtrusionType != Obj3dType.o3d_baseLoft) { if (parameters.ExtrudableEntity == null) { LastErrorCode = ErrorCodes.ExtrudableEntityNotSet; return; } } bool normalDirection = true; if (extrusionType == ExtrusionType.ByEntity) { if (parameters.Direction == Direction_Type.dtNormal) { normalDirection = true; } else if (parameters.Direction == Direction_Type.dtReverse) { normalDirection = false; } else { LastErrorCode = ErrorCodes.ExtrusionDirectionNotSupported; return; } if (parameters.Depth == default(double) || !DoubleValidator.Validate(parameters.Depth)) { LastErrorCode = ErrorCodes.ArgumentInvalid; return; } } var faceCollection = (ksEntityCollection)parameters.Document3DPart. EntityCollection((short)Obj3dType.o3d_face); _facesCountBeforeExtrusion = faceCollection.GetCount(); switch (extrusionType) { case ExtrusionType.ByEntity: if (!CreateExtrusionByDirection( entity, parameters, normalDirection)) { return; } break; case ExtrusionType.BySketchesCollection: if (!CreateExtrusionBySketchCollection( entity, parameters)) { return; } break; } _doc3DPart = parameters.Document3DPart; faceCollection.refresh(); _facesCountAfterExtrusion = faceCollection.GetCount(); if (_facesCountAfterExtrusion == _facesCountBeforeExtrusion) { LastErrorCode = ErrorCodes.ExtrusionFacesCountWrong; return; } }
/// <summary> /// Вернуть грань, параллельную базовой грани /// </summary> /// Этот алгоритм использует области сбора граней в диапазоне от начального индекса до конечного индекса. /// Суть алгоритма заключается в том, что любая вытянутая фигура /// имеет верхнюю и нижнюю плоскости и параллельные плоскости, и области этих плоскостей равны боковым плоскостям! /// Но все отсортированы случайным образом. /// Если мы добавим любую фигуру в нижнюю плоскость /// (т.е.создать эскиз и выдавить его на нижнюю плоскость), тогда площадь нижней плоскости уменьшается, /// и мы можем точно сказать, какой индекс принадлежит каждой плоскости /// <param name="_doc3DPart">Kompas part of 3D document</param> /// <param name="startIndex">Face collection start index</param> /// <param name="endIndex">Face collection end index</param> /// <param name="outFirstIndex">First base plane index in faces collection</param> /// <param name="outSecondIndex">Second base plane index in faces collection</param> public static void GetRegPolyBasePlanesIndexes(ksPart _doc3DPart, int startIndex, int endIndex, out int outFirstIndex, out int outSecondIndex) { // Collection of entities in all figure var faceCollection = (ksEntityCollection)_doc3DPart.EntityCollection((short)Obj3dType.o3d_face); List <double> initList = new List <double>(); List <double> unroundedList = new List <double>(); List <double> uniqList = new List <double>(); List <double> notUniqList = new List <double>(); if (faceCollection == null || !DoubleValidator.Validate(startIndex) || !DoubleValidator.Validate(endIndex) ) { outFirstIndex = outSecondIndex = -1; return; } int firstIndex = startIndex - 1; int secondIndex = startIndex - 1; // Set figure faces areas list with all areas for (int i = startIndex - 1; i < endIndex; i++) { uint ST_MIX_SM = 0x0; //это похоже на определение "области в сантиметрах" в API var entity = (ksEntity)faceCollection.GetByIndex(i); var def = (ksFaceDefinition)entity.GetDefinition(); // Get unrounded area of plane var area = def.GetArea(ST_MIX_SM); unroundedList.Add(area); } // Get minimal epsilon for all unrounded areas var minimalEpsilon = GetMinimalEspilonOfAreas(unroundedList); // Установить список инициализации с округленными значениями for (int i = 0, length = unroundedList.Count; i < length; i++) { initList.Add(Math.Round(unroundedList[i], minimalEpsilon)); } // Получить уникальные области в списке for (int i = 0, length = initList.Count; i < length; i++) { // if значение не задано ни в уникальном, ни в неуникальном списке - // else установить его в уникальный список if (!uniqList.Contains(initList[i])) { if (!notUniqList.Contains(initList[i])) { uniqList.Add(initList[i]); } } else { // Else если он уже указан в уникальном списке - // -- удалить из этого списка и установить его в неуникальный список, но только один раз uniqList.Remove(initList[i]); notUniqList.Add(initList[i]); } } // Проверьте эти 2 индекса на смежность с базовой гранью фигуры if (uniqList.Count == 2) { firstIndex += initList.IndexOf(uniqList[0]); secondIndex += initList.IndexOf(uniqList[1]); } // Else если площадь основной базовой поверхности выше, чем площадь параллельной базовой поверхности // -- затем вернуть только первый индекс else if (uniqList.Count == 1) { firstIndex += initList.IndexOf(uniqList[0]); secondIndex = -1; } // Else если параллельные грани не имеют одинаковую площадь -- // -- затем получить значение, которое повторяется дважды в массиве else if (uniqList.Count == 0) { bool getFirstElement = false; for (int i = 0, count = initList.Count; i < count; i++) { bool isTwoElements = (GetElementCountInList(initList, initList[i]) == 2); if ((isTwoElements == true) && (getFirstElement == false)) { firstIndex += i; getFirstElement = true; } else if ((isTwoElements == true) && (getFirstElement == true)) { secondIndex += i; break; } } } else { firstIndex = secondIndex = -1; } outFirstIndex = firstIndex; outSecondIndex = secondIndex; }