Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
표시
레이아웃
나란히 보기
합쳐 보기
실시간 편집
공백 변경 숨기기
변경 없는 행 숨기기
줄바꿈 비활성화
비교 단위
스마트
구문
없음
모양 변경
처리
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
Untitled diff
생성일
10년 전
비교 결과 만료 없음
초기화
내보내기
공유
설명
11 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
357 행
복사
51 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
386 행
복사
/*
/*
T-Slot Joint
T-Slot Joint
This custom feature adds a bolted T-slot connection between two planar parts.
This custom feature adds a bolted T-slot connection between two planar parts.
Version 1.0 - July 6, 2016 - Arul Suresh - Initial development and validation.
Version 1.0 - July 6, 2016 - Arul Suresh - Initial development and validation.
Version 2.0 - July 20, 2016 - Arul Suresh - Added some utility functions, lookup tables.
Version 2.0 - July 20, 2016 - Arul Suresh - Added some utility functions, lookup tables.
Initial forum release.
Initial forum release.
Version 2.1 - Sept 18, 2016 - Arul Suresh - Update to newest FS, published release.
Version 2.1 - Sept 18, 2016 - Arul Suresh - Update to newest FS, published release.
Version 2.1.1 - Sept 18, 2016 - Arul Suresh - Document description.
Version 2.1.1 - Sept 18, 2016 - Arul Suresh - Document description.
복사
복사됨
복사
복사됨
Version 2.2 - April 7, 2017 - Eric Miller - Added single-hole centered spacing and multiple plane selection, and fixed handling of angled surfaces.
*/
*/
FeatureScript 422;
FeatureScript 422;
import(path : "onshape/std/geometry.fs", version : "422.0");
import(path : "onshape/std/geometry.fs", version : "422.0");
복사
복사됨
복사
복사됨
import(path : "
4dfdd9c6856db10dd896e29b
", version : "
c92857bc5898d90ad6f21cc3
");
import(path : "
5695a84e0bdf321f1d91df84
", version : "
90245e5cbffb04b2d7c533ad
");
import(path : "f4e7238da5afaf5a3f1498c0/962c2d4fc4ca0f12fa54d8f4/22d17eb94c85900576fbf53e", version : "130b19167f35ae1dc291873b");
import(path : "f4e7238da5afaf5a3f1498c0/962c2d4fc4ca0f12fa54d8f4/22d17eb94c85900576fbf53e", version : "130b19167f35ae1dc291873b");
annotation { "Feature Type Name" : "T-Slot Joint", "Editing Logic Function" : "tsEditLogic" }
annotation { "Feature Type Name" : "T-Slot Joint", "Editing Logic Function" : "tsEditLogic" }
export const tSlotJoint = defineFeature(function(context is Context, id is Id, definition is map)
export const tSlotJoint = defineFeature(function(context is Context, id is Id, definition is map)
precondition
precondition
{
{
복사
복사됨
복사
복사됨
annotation { "Name" : "Choose edge face", "Filter" : EntityType.FACE && SketchObject.NO
, "MaxNumberOfPicks" : 1
}
annotation { "Name" : "Choose edge face", "Filter" : EntityType.FACE && SketchObject.NO
}
definition.base is Query;
definition.base is Query;
annotation { "Name" : "Standard", "Lookup Table" : tSlotTable, "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
annotation { "Name" : "Standard", "Lookup Table" : tSlotTable, "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
definition.connectorStandard is LookupTablePath;
definition.connectorStandard is LookupTablePath;
annotation { "Name" : "Clearance diameter", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
annotation { "Name" : "Clearance diameter", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
isLength(definition.holeD, TSLOT_DIAMETER_LENGTH_BOUNDS);
isLength(definition.holeD, TSLOT_DIAMETER_LENGTH_BOUNDS);
annotation { "Name" : "Nut width", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
annotation { "Name" : "Nut width", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
isLength(definition.nutW, TSLOT_NUT_W_LENGTH_BOUNDS);
isLength(definition.nutW, TSLOT_NUT_W_LENGTH_BOUNDS);
annotation { "Name" : "Nut thickness", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
annotation { "Name" : "Nut thickness", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
isLength(definition.nutT, TSLOT_NUT_T_LENGTH_BOUNDS);
isLength(definition.nutT, TSLOT_NUT_T_LENGTH_BOUNDS);
annotation { "Name" : "Show nut allowance", "UIHint" : "ALWAYS_HIDDEN" }
annotation { "Name" : "Show nut allowance", "UIHint" : "ALWAYS_HIDDEN" }
definition.showNutA is boolean;
definition.showNutA is boolean;
if (definition.showNutA)
if (definition.showNutA)
{
{
annotation { "Name" : "Nut allowance" }
annotation { "Name" : "Nut allowance" }
isLength(definition.nutA, LENGTH_BOUNDS);
isLength(definition.nutA, LENGTH_BOUNDS);
}
}
annotation { "Name" : "Screw length", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
annotation { "Name" : "Screw length", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
isLength(definition.screwLen, TSLOT_SCREWLEN_LENGTH_BOUNDS);
isLength(definition.screwLen, TSLOT_SCREWLEN_LENGTH_BOUNDS);
annotation { "Name" : "Hole termination face", "Filter" : EntityType.FACE, "MaxNumberOfPicks" : 1 }
annotation { "Name" : "Hole termination face", "Filter" : EntityType.FACE, "MaxNumberOfPicks" : 1 }
definition.terminationFace is Query;
definition.terminationFace is Query;
annotation { "Name" : "Switch start side" }
annotation { "Name" : "Switch start side" }
definition.switchStart is boolean;
definition.switchStart is boolean;
annotation { "Name" : "Space from edge", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
annotation { "Name" : "Space from edge", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
isLength(definition.edgeSpace, TSLOT_EDGE_LENGTH_BOUNDS);
isLength(definition.edgeSpace, TSLOT_EDGE_LENGTH_BOUNDS);
annotation { "Name" : "# of connectors" }
annotation { "Name" : "# of connectors" }
isInteger(definition.numConnectors, NUM_CONN_BOUNDS);
isInteger(definition.numConnectors, NUM_CONN_BOUNDS);
복사
복사됨
복사
복사됨
annotation { "Name" : "Equal spacing"
}
annotation { "Name" : "Equal spacing"
, "Default": true
}
definition.equalSpacing is boolean;
definition.equalSpacing is boolean;
if (!definition.equalSpacing)
if (!definition.equalSpacing)
{
{
annotation { "Name" : "Spacing", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
annotation { "Name" : "Spacing", "UIHint" : "REMEMBER_PREVIOUS_VALUE" }
isLength(definition.spacing, TSLOT_SPACING_LENGTH_BOUNDS);
isLength(definition.spacing, TSLOT_SPACING_LENGTH_BOUNDS);
annotation { "Name" : "Symmetric" }
annotation { "Name" : "Symmetric" }
definition.symmetric is boolean;
definition.symmetric is boolean;
}
}
}
}
{
{
복사
복사됨
복사
복사됨
var faceInfo
= getFaceInfo(context, definition
);
var bases = evaluateQuery(context, definition.base);
var faceInfo;
var i = 0;
for (var base in bases)
{
i += 1;
faceInfo
= getFaceInfo(context, definition
, base
);
복사
복사됨
복사
복사됨
var connectionPoints is array = getConnectionPoints(context, definition, faceInfo);
var connectionPoints is array = getConnectionPoints(context, definition, faceInfo);
복사
복사됨
복사
복사됨
var connectionCount = 0;
var connectionCount = 0;
for (var connPoint in connectionPoints)
for (var connPoint in connectionPoints)
{
{
connectionCount += 1;
connectionCount += 1;
createTSlotJoint(context, id + ("tsj"
~ connectionCount), definition, connPoint
);
createTSlotJoint(context, id + ("tsj"
~ i
~ connectionCount), definition, connPoint
, base);
}
}
}
});
});
/*
/*
* Creates geometry for a single T-Slot at the provided coordinate frame.
* Creates geometry for a single T-Slot at the provided coordinate frame.
*/
*/
복사
복사됨
복사
복사됨
function createTSlotJoint(context is Context, id is Id, definition is map, csys is CoordSystem
)
function createTSlotJoint(context is Context, id is Id, definition is map, csys is CoordSystem
, base is Query
)
{
{
var endClearance = 0.25 * definition.holeD;
var endClearance = 0.25 * definition.holeD;
// hole through continuous material
// hole through continuous material
var holeSketchPlane = plane(csys.origin, csys.zAxis, csys.xAxis);
var holeSketchPlane = plane(csys.origin, csys.zAxis, csys.xAxis);
var depth = undefined;
var depth = undefined;
if (evaluateQuery(context, definition.terminationFace) != [])
if (evaluateQuery(context, definition.terminationFace) != [])
{
{
var faceCoords = evPlane(context, {
var faceCoords = evPlane(context, {
"face" : definition.terminationFace
"face" : definition.terminationFace
}).origin;
}).origin;
depth = fromWorld(csys, faceCoords)[2];
depth = fromWorld(csys, faceCoords)[2];
저장된 비교 결과
원본
파일 열기
/* T-Slot Joint This custom feature adds a bolted T-slot connection between two planar parts. Version 1.0 - July 6, 2016 - Arul Suresh - Initial development and validation. Version 2.0 - July 20, 2016 - Arul Suresh - Added some utility functions, lookup tables. Initial forum release. Version 2.1 - Sept 18, 2016 - Arul Suresh - Update to newest FS, published release. Version 2.1.1 - Sept 18, 2016 - Arul Suresh - Document description. */ FeatureScript 422; import(path : "onshape/std/geometry.fs", version : "422.0"); import(path : "4dfdd9c6856db10dd896e29b", version : "c92857bc5898d90ad6f21cc3"); import(path : "f4e7238da5afaf5a3f1498c0/962c2d4fc4ca0f12fa54d8f4/22d17eb94c85900576fbf53e", version : "130b19167f35ae1dc291873b"); annotation { "Feature Type Name" : "T-Slot Joint", "Editing Logic Function" : "tsEditLogic" } export const tSlotJoint = defineFeature(function(context is Context, id is Id, definition is map) precondition { annotation { "Name" : "Choose edge face", "Filter" : EntityType.FACE && SketchObject.NO, "MaxNumberOfPicks" : 1 } definition.base is Query; annotation { "Name" : "Standard", "Lookup Table" : tSlotTable, "UIHint" : "REMEMBER_PREVIOUS_VALUE" } definition.connectorStandard is LookupTablePath; annotation { "Name" : "Clearance diameter", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.holeD, TSLOT_DIAMETER_LENGTH_BOUNDS); annotation { "Name" : "Nut width", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.nutW, TSLOT_NUT_W_LENGTH_BOUNDS); annotation { "Name" : "Nut thickness", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.nutT, TSLOT_NUT_T_LENGTH_BOUNDS); annotation { "Name" : "Show nut allowance", "UIHint" : "ALWAYS_HIDDEN" } definition.showNutA is boolean; if (definition.showNutA) { annotation { "Name" : "Nut allowance" } isLength(definition.nutA, LENGTH_BOUNDS); } annotation { "Name" : "Screw length", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.screwLen, TSLOT_SCREWLEN_LENGTH_BOUNDS); annotation { "Name" : "Hole termination face", "Filter" : EntityType.FACE, "MaxNumberOfPicks" : 1 } definition.terminationFace is Query; annotation { "Name" : "Switch start side" } definition.switchStart is boolean; annotation { "Name" : "Space from edge", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.edgeSpace, TSLOT_EDGE_LENGTH_BOUNDS); annotation { "Name" : "# of connectors" } isInteger(definition.numConnectors, NUM_CONN_BOUNDS); annotation { "Name" : "Equal spacing" } definition.equalSpacing is boolean; if (!definition.equalSpacing) { annotation { "Name" : "Spacing", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.spacing, TSLOT_SPACING_LENGTH_BOUNDS); annotation { "Name" : "Symmetric" } definition.symmetric is boolean; } } { var faceInfo = getFaceInfo(context, definition); var connectionPoints is array = getConnectionPoints(context, definition, faceInfo); var connectionCount = 0; for (var connPoint in connectionPoints) { connectionCount += 1; createTSlotJoint(context, id + ("tsj" ~ connectionCount), definition, connPoint); } }); /* * Creates geometry for a single T-Slot at the provided coordinate frame. */ function createTSlotJoint(context is Context, id is Id, definition is map, csys is CoordSystem) { var endClearance = 0.25 * definition.holeD; // hole through continuous material var holeSketchPlane = plane(csys.origin, csys.zAxis, csys.xAxis); var depth = undefined; if (evaluateQuery(context, definition.terminationFace) != []) { var faceCoords = evPlane(context, { "face" : definition.terminationFace }).origin; depth = fromWorld(csys, faceCoords)[2]; } else { depth = getContinuousDepth(context, id + "cd", { "csys" : csys, "D" : definition.holeD }); } if (definition.screwLen - depth - definition.nutT - endClearance < 0) { throw regenError("Screw length is too short for desired connection.", ["screwLen"]); } var sketch = newSketchOnPlane(context, id + "holeSketch", { "sketchPlane" : holeSketchPlane }); skCircle(sketch, "clearanceHole", { "center" : vector(0, 0) * inch, "radius" : 0.5 * definition.holeD }); skSolve(sketch); if (tolerantEquals(depth, 0 * meter)) { throw regenError("Edge connection does not intersect any clamped parts.", qCreatedBy(id + "holeSketch", EntityType.EDGE)); } extrude(context, id + "cutHole", { "entities" : qSketchRegion(id + "holeSketch"), "endBound" : BoundingType.BLIND, "depth" : depth, "operationType" : NewBodyOperationType.REMOVE }); opDeleteBodies(context, id + "deleteHoleSketch", { "entities" : qCreatedBy(id + "holeSketch", EntityType.BODY) }); // At this point, hole is cut, and depth stores how much of the bolt is in clamped material // Generate a sketch and cut out the slot for the thread/nut var threadSketchPlane = plane(csys.origin, yAxis(csys), csys.xAxis); var threadSketch = newSketchOnPlane(context, id + "threadsketch", { "sketchPlane" : threadSketchPlane }); skRectangle(threadSketch, "screwPocket", { "firstCorner" : vector(-0.5 * definition.holeD, 0 * meter), "secondCorner" : vector(0.5 * definition.holeD, (definition.screwLen + 2 * definition.nutA) - depth) }); skRectangle(threadSketch, "nutPocket", { "firstCorner" : vector(-0.5 * definition.nutW - definition.nutA, definition.screwLen - depth - endClearance - (definition.nutT + 2 * definition.nutA)), "secondCorner" : vector(0.5 * definition.nutW + definition.nutA, definition.screwLen - depth - endClearance) }); skSolve(threadSketch); extrude(context, id + "threadExtrude", { "entities" : qSketchRegion(id + "threadsketch"), "endBound" : BoundingType.THROUGH_ALL, "hasSecondDirection" : true, "secondDirectionBound" : SecondDirectionBoundingType.THROUGH_ALL, "operationType" : NewBodyOperationType.REMOVE, "defaultScope" : false, "booleanScope" : qOwnerBody(definition.base) }); opDeleteBodies(context, id + "deleteThreadSketch", { "entities" : qCreatedBy(id + "threadsketch", EntityType.BODY) }); } /* * Returns a coordinate system and bounding box for the provided face */ function getFaceInfo(context is Context, definition is map) returns map { if (size(evaluateQuery(context, definition.base)) != 1) { throw regenError("Cannot generate without edge face selection", ["base"]); } var facePlane = evPlane(context, { "face" : definition.base }); var defaultCSys = planeToCSys(facePlane); var bbox = evBox3d(context, { "topology" : definition.base, "cSys" : defaultCSys }); var xrange = bbox.maxCorner[0] - bbox.minCorner[0]; var yrange = bbox.maxCorner[1] - bbox.minCorner[1]; // generate a coordinate system such that x is along the long dimension of the face var csys is CoordSystem = coordSystem(facePlane.origin, (xrange > yrange) ? defaultCSys.xAxis : yAxis(defaultCSys), facePlane.normal); bbox = evBox3d(context, { "topology" : definition.base, "cSys" : csys }); return { "csys" : csys, "bbox" : bbox }; } /* * Given feature parameters and face selection, generates array of points at which T-Slots will be created */ function getConnectionPoints(context is Context, definition is map, faceInfo is map) returns array { if (definition.equalSpacing) { definition.symmetric = false; var length = faceInfo.bbox.maxCorner[0] - faceInfo.bbox.minCorner[0]; definition.spacing = (length - 2 * definition.edgeSpace) / (definition.numConnectors - 1); } var coordList = makeCoordArray(context, definition, faceInfo); if (definition.symmetric) { var localDefinition = definition; localDefinition.switchStart = !localDefinition.switchStart; var symmetricCoordList = makeCoordArray(context, localDefinition, faceInfo); coordList = concatenateArrays([coordList, symmetricCoordList]); } return coordList; } function makeCoordArray(context is Context, definition is map, faceInfo is map) returns array { var coordArray is array = makeArray(definition.numConnectors); var sense = (definition.switchStart) ? -1 : 1; var startx = ((definition.switchStart) ? faceInfo.bbox.maxCorner[0] : faceInfo.bbox.minCorner[0]) + sense * definition.edgeSpace; var dir = faceInfo.csys.xAxis; var startOrigin = faceInfo.csys.origin + startx * dir; for (var i = 0; i < definition.numConnectors; i += 1) { coordArray[i] = coordSystem(startOrigin + sense * definition.spacing * dir * i, dir, faceInfo.csys.zAxis); } return coordArray; } export function tsEditLogic(context is Context, id is Id, oldDefinition is map, definition is map, isCreating is boolean, specifiedParameters is map, hiddenBodies is Query) returns map { if (oldDefinition.connectorStandard != definition.connectorStandard) { definition = updateTSDefinitionWithStandard(oldDefinition, definition); } definition = setToCustomIfStandardViolated(definition); if (definition.equalSpacing) { definition.numConnectors = max(2, definition.numConnectors); } return definition; } export function updateTSDefinitionWithStandard(oldDefinition is map, definition is map) returns map { var table = getLookupTable(tSlotTable, definition.connectorStandard); definition.showNutA = false; for (var entry in table) { definition[entry.key] = lookupTableFixExpression(entry.value); } return definition; } function setToCustomIfStandardViolated(definition is map) returns map { var table = getLookupTable(tSlotTable, definition.connectorStandard); if (isLookupTableViolated(definition, table)) { definition.connectorStandard = lookupTablePath({ "standard" : "Custom" }); definition.showNutA = true; } return definition; } export const NUM_CONN_BOUNDS = { "min" : 1, "max" : 500, (unitless) : [1, 1, 500] } as IntegerBoundSpec; export const TSLOT_DIAMETER_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.1285, 19685] } as LengthBoundSpec; export const TSLOT_NUT_W_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.25, 19685] } as LengthBoundSpec; export const TSLOT_NUT_T_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.09375, 19685] } as LengthBoundSpec; export const TSLOT_SCREWLEN_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.625, 19685], (millimeter) : 15, (centimeter) : 1.5 } as LengthBoundSpec; export const TSLOT_EDGE_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.5, 19685], (millimeter) : 10, (centimeter) : 1 } as LengthBoundSpec; export const TSLOT_SPACING_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.375, 19685], (millimeter) : 10, (centimeter) : 1 } as LengthBoundSpec;
수정본
파일 열기
/* T-Slot Joint This custom feature adds a bolted T-slot connection between two planar parts. Version 1.0 - July 6, 2016 - Arul Suresh - Initial development and validation. Version 2.0 - July 20, 2016 - Arul Suresh - Added some utility functions, lookup tables. Initial forum release. Version 2.1 - Sept 18, 2016 - Arul Suresh - Update to newest FS, published release. Version 2.1.1 - Sept 18, 2016 - Arul Suresh - Document description. Version 2.2 - April 7, 2017 - Eric Miller - Added single-hole centered spacing and multiple plane selection, and fixed handling of angled surfaces. */ FeatureScript 422; import(path : "onshape/std/geometry.fs", version : "422.0"); import(path : "5695a84e0bdf321f1d91df84", version : "90245e5cbffb04b2d7c533ad"); import(path : "f4e7238da5afaf5a3f1498c0/962c2d4fc4ca0f12fa54d8f4/22d17eb94c85900576fbf53e", version : "130b19167f35ae1dc291873b"); annotation { "Feature Type Name" : "T-Slot Joint", "Editing Logic Function" : "tsEditLogic" } export const tSlotJoint = defineFeature(function(context is Context, id is Id, definition is map) precondition { annotation { "Name" : "Choose edge face", "Filter" : EntityType.FACE && SketchObject.NO } definition.base is Query; annotation { "Name" : "Standard", "Lookup Table" : tSlotTable, "UIHint" : "REMEMBER_PREVIOUS_VALUE" } definition.connectorStandard is LookupTablePath; annotation { "Name" : "Clearance diameter", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.holeD, TSLOT_DIAMETER_LENGTH_BOUNDS); annotation { "Name" : "Nut width", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.nutW, TSLOT_NUT_W_LENGTH_BOUNDS); annotation { "Name" : "Nut thickness", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.nutT, TSLOT_NUT_T_LENGTH_BOUNDS); annotation { "Name" : "Show nut allowance", "UIHint" : "ALWAYS_HIDDEN" } definition.showNutA is boolean; if (definition.showNutA) { annotation { "Name" : "Nut allowance" } isLength(definition.nutA, LENGTH_BOUNDS); } annotation { "Name" : "Screw length", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.screwLen, TSLOT_SCREWLEN_LENGTH_BOUNDS); annotation { "Name" : "Hole termination face", "Filter" : EntityType.FACE, "MaxNumberOfPicks" : 1 } definition.terminationFace is Query; annotation { "Name" : "Switch start side" } definition.switchStart is boolean; annotation { "Name" : "Space from edge", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.edgeSpace, TSLOT_EDGE_LENGTH_BOUNDS); annotation { "Name" : "# of connectors" } isInteger(definition.numConnectors, NUM_CONN_BOUNDS); annotation { "Name" : "Equal spacing", "Default": true } definition.equalSpacing is boolean; if (!definition.equalSpacing) { annotation { "Name" : "Spacing", "UIHint" : "REMEMBER_PREVIOUS_VALUE" } isLength(definition.spacing, TSLOT_SPACING_LENGTH_BOUNDS); annotation { "Name" : "Symmetric" } definition.symmetric is boolean; } } { var bases = evaluateQuery(context, definition.base); var faceInfo; var i = 0; for (var base in bases) { i += 1; faceInfo = getFaceInfo(context, definition, base); var connectionPoints is array = getConnectionPoints(context, definition, faceInfo); var connectionCount = 0; for (var connPoint in connectionPoints) { connectionCount += 1; createTSlotJoint(context, id + ("tsj" ~ i ~ connectionCount), definition, connPoint, base); } } }); /* * Creates geometry for a single T-Slot at the provided coordinate frame. */ function createTSlotJoint(context is Context, id is Id, definition is map, csys is CoordSystem, base is Query) { var endClearance = 0.25 * definition.holeD; // hole through continuous material var holeSketchPlane = plane(csys.origin, csys.zAxis, csys.xAxis); var depth = undefined; if (evaluateQuery(context, definition.terminationFace) != []) { var faceCoords = evPlane(context, { "face" : definition.terminationFace }).origin; depth = fromWorld(csys, faceCoords)[2]; } else { depth = getContinuousDepth(context, id + "cd", { "csys" : csys, "D" : definition.holeD }); } if (definition.screwLen - depth - definition.nutT - endClearance < 0) { throw regenError("Screw length is too short for desired connection.", ["screwLen"]); } var sketch = newSketchOnPlane(context, id + "holeSketch", { "sketchPlane" : holeSketchPlane }); skCircle(sketch, "clearanceHole", { "center" : vector(0, 0) * inch, "radius" : 0.5 * definition.holeD }); skSolve(sketch); if (tolerantEquals(depth, 0 * meter)) { throw regenError("Edge connection does not intersect any clamped parts.", qCreatedBy(id + "holeSketch", EntityType.EDGE)); } extrude(context, id + "cutHole", { "entities" : qSketchRegion(id + "holeSketch"), "endBound" : BoundingType.BLIND, "depth" : depth, "operationType" : NewBodyOperationType.REMOVE }); opDeleteBodies(context, id + "deleteHoleSketch", { "entities" : qCreatedBy(id + "holeSketch", EntityType.BODY) }); // At this point, hole is cut, and depth stores how much of the bolt is in clamped material // Generate a sketch and cut out the slot for the thread/nut var threadSketchPlane = plane(csys.origin, yAxis(csys), csys.xAxis); var threadSketch = newSketchOnPlane(context, id + "threadsketch", { "sketchPlane" : threadSketchPlane }); skRectangle(threadSketch, "screwPocket", { "firstCorner" : vector(-0.5 * definition.holeD, 0 * meter), "secondCorner" : vector(0.5 * definition.holeD, (definition.screwLen + 2 * definition.nutA) - depth) }); skRectangle(threadSketch, "nutPocket", { "firstCorner" : vector(-0.5 * definition.nutW - definition.nutA, definition.screwLen - depth - endClearance - (definition.nutT + 2 * definition.nutA)), "secondCorner" : vector(0.5 * definition.nutW + definition.nutA, definition.screwLen - depth - endClearance) }); skSolve(threadSketch); extrude(context, id + "threadExtrude", { "entities" : qSketchRegion(id + "threadsketch"), "endBound" : BoundingType.THROUGH_ALL, "hasSecondDirection" : true, "secondDirectionBound" : SecondDirectionBoundingType.THROUGH_ALL, "operationType" : NewBodyOperationType.REMOVE, "defaultScope" : false, "booleanScope" : qOwnerBody(base) }); opDeleteBodies(context, id + "deleteThreadSketch", { "entities" : qCreatedBy(id + "threadsketch", EntityType.BODY) }); } /* * Returns a coordinate system and bounding box for the provided face */ function getFaceInfo(context is Context, definition is map, base is Query) returns map { if (size(evaluateQuery(context, base)) != 1) { throw regenError("Cannot generate without edge face selection", ["base"]); } var facePlane = evPlane(context, { "face" : base }); var defaultCSys = planeToCSys(facePlane) as CoordSystem; try { var longEdge = qNthElement(qLargest(qGeometry(qEdgeAdjacent(base, EntityType.EDGE), GeometryType.LINE)), 0); var axis = evAxis(context, { "axis" : longEdge }) as Line; defaultCSys.xAxis = axis.direction; } var bbox = evBox3d(context, { "topology" : base, "cSys" : defaultCSys }); var xrange = bbox.maxCorner[0] - bbox.minCorner[0]; var yrange = bbox.maxCorner[1] - bbox.minCorner[1]; // generate a coordinate system such that x is along the long dimension of the face var csys is CoordSystem = coordSystem(facePlane.origin, (xrange > yrange) ? defaultCSys.xAxis : yAxis(defaultCSys), facePlane.normal); bbox = evBox3d(context, { "topology" : base, "cSys" : csys }); return { "csys" : csys, "bbox" : bbox }; } /* * Given feature parameters and face selection, generates array of points at which T-Slots will be created */ function getConnectionPoints(context is Context, definition is map, faceInfo is map) returns array { if (definition.equalSpacing) { definition.symmetric = false; var length = faceInfo.bbox.maxCorner[0] - faceInfo.bbox.minCorner[0]; if (definition.numConnectors > 1) { definition.spacing = (length - 2 * definition.edgeSpace) / (definition.numConnectors - 1); } else { definition.edgeSpace = length / 2; } } var coordList = makeCoordArray(context, definition, faceInfo); if (definition.symmetric) { var localDefinition = definition; localDefinition.switchStart = !localDefinition.switchStart; var symmetricCoordList = makeCoordArray(context, localDefinition, faceInfo); coordList = concatenateArrays([coordList, symmetricCoordList]); } return coordList; } function makeCoordArray(context is Context, definition is map, faceInfo is map) returns array { var coordArray is array = makeArray(definition.numConnectors); var sense = (definition.switchStart) ? -1 : 1; var startx = ((definition.switchStart) ? faceInfo.bbox.maxCorner[0] : faceInfo.bbox.minCorner[0]) + sense * definition.edgeSpace; var dir = faceInfo.csys.xAxis; var startOrigin = faceInfo.csys.origin + startx * dir; for (var i = 0; i < definition.numConnectors; i += 1) { coordArray[i] = coordSystem(startOrigin + sense * definition.spacing * dir * i, dir, faceInfo.csys.zAxis); } return coordArray; } export function tsEditLogic(context is Context, id is Id, oldDefinition is map, definition is map, isCreating is boolean, specifiedParameters is map, hiddenBodies is Query) returns map { if (oldDefinition.connectorStandard != definition.connectorStandard) { definition = updateTSDefinitionWithStandard(oldDefinition, definition); } definition = setToCustomIfStandardViolated(definition); // if (definition.equalSpacing) // { // definition.numConnectors = max(2, definition.numConnectors); // } return definition; } export function updateTSDefinitionWithStandard(oldDefinition is map, definition is map) returns map { var table = getLookupTable(tSlotTable, definition.connectorStandard); definition.showNutA = false; for (var entry in table) { definition[entry.key] = lookupTableFixExpression(entry.value); } return definition; } function setToCustomIfStandardViolated(definition is map) returns map { var table = getLookupTable(tSlotTable, definition.connectorStandard); if (isLookupTableViolated(definition, table)) { definition.connectorStandard = lookupTablePath({ "standard" : "Custom" }); definition.showNutA = true; } return definition; } export const NUM_CONN_BOUNDS = { "min" : 1, "max" : 500, (unitless) : [1, 1, 500] } as IntegerBoundSpec; export const TSLOT_DIAMETER_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.1285, 19685] } as LengthBoundSpec; export const TSLOT_NUT_W_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.25, 19685] } as LengthBoundSpec; export const TSLOT_NUT_T_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.09375, 19685] } as LengthBoundSpec; export const TSLOT_SCREWLEN_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.625, 19685], (millimeter) : 15, (centimeter) : 1.5 } as LengthBoundSpec; export const TSLOT_EDGE_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.5, 19685], (millimeter) : 10, (centimeter) : 1 } as LengthBoundSpec; export const TSLOT_SPACING_LENGTH_BOUNDS = { "min" : -TOLERANCE.zeroLength * meter, "max" : 500 * meter, (inch) : [1e-4, 0.375, 19685], (millimeter) : 10, (centimeter) : 1 } as LengthBoundSpec;
비교하기