fix(label): ,/
This commit is contained in:
@@ -1692,29 +1692,6 @@ const LabelPage = ({
|
||||
[]
|
||||
)
|
||||
|
||||
const removeObjectFromGroupMap = useCallback(
|
||||
(imageId: string, id: number) => {
|
||||
const nextPathGroupMap = safeClone(
|
||||
useRightToolsStore.getState().pathGroupMap
|
||||
)
|
||||
const imageGroupMap = nextPathGroupMap.get(imageId)
|
||||
if (!imageGroupMap) return
|
||||
|
||||
for (let [groupId, pathIds] of imageGroupMap.entries()) {
|
||||
const nextPathIds = pathIds.filter((pathId) => pathId !== id)
|
||||
if (nextPathIds.length > 1) {
|
||||
imageGroupMap.set(groupId, nextPathIds)
|
||||
} else {
|
||||
imageGroupMap.delete(groupId)
|
||||
}
|
||||
}
|
||||
|
||||
if (!imageGroupMap.size) nextPathGroupMap.delete(imageId)
|
||||
useRightToolsStore.getState().setPathGroupMap(nextPathGroupMap)
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
const handleContinueSelectedPolygon = useCallback(() => {
|
||||
const selectedContext = resolveSelectedObjectContext()
|
||||
if (!selectedContext) {
|
||||
@@ -1758,70 +1735,6 @@ const LabelPage = ({
|
||||
setPressA,
|
||||
])
|
||||
|
||||
const hasShapeSegments = useCallback((shape: any) => {
|
||||
if (!shape) return false
|
||||
if (shape instanceof paper.CompoundPath) {
|
||||
return (shape.children as paper.Path[]).some(
|
||||
(child) => child.segments?.length
|
||||
)
|
||||
}
|
||||
if (shape instanceof paper.Path) {
|
||||
return !!shape.segments?.length
|
||||
}
|
||||
return false
|
||||
}, [])
|
||||
|
||||
const createWorkingPolygonShape = useCallback((items: any[]) => {
|
||||
const compound = items.find((item) => item instanceof paper.CompoundPath)
|
||||
if (compound) {
|
||||
return (compound as paper.CompoundPath).clone({ insert: false }) as
|
||||
| paper.Path
|
||||
| paper.CompoundPath
|
||||
}
|
||||
|
||||
const paths = items.filter(
|
||||
(item) => item instanceof paper.Path
|
||||
) as paper.Path[]
|
||||
if (!paths.length) return null
|
||||
if (paths.length === 1) {
|
||||
return paths[0].clone({ insert: false }) as
|
||||
| paper.Path
|
||||
| paper.CompoundPath
|
||||
}
|
||||
|
||||
const merged = new paper.CompoundPath({ insert: false })
|
||||
paths.forEach((path) => {
|
||||
merged.addChild(path.clone({ insert: false }))
|
||||
})
|
||||
return merged as paper.Path | paper.CompoundPath
|
||||
}, [])
|
||||
|
||||
const collectPolygonPoints = useCallback(
|
||||
(shape: paper.Path | paper.CompoundPath) => {
|
||||
const polygonPoints: any[] = []
|
||||
const polygonHollowPoints: any[] = []
|
||||
|
||||
const collectPath = (path: paper.Path) => {
|
||||
if (!path.segments?.length) return
|
||||
const pathData = JSON.parse(path.exportJSON({ precision: 20 }))
|
||||
if (path.clockwise) {
|
||||
polygonPoints.push(pathData[1]?.segments)
|
||||
} else {
|
||||
polygonHollowPoints.push(pathData[1]?.segments)
|
||||
}
|
||||
}
|
||||
|
||||
if (shape instanceof paper.CompoundPath) {
|
||||
;(shape.children as paper.Path[]).forEach((path) => collectPath(path))
|
||||
} else {
|
||||
collectPath(shape)
|
||||
}
|
||||
|
||||
return { polygonPoints, polygonHollowPoints }
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
const applySelectedPolygonOverlap = useCallback(
|
||||
(mode: "subtract" | "unite") => {
|
||||
const selectedContext = resolveSelectedObjectContext()
|
||||
@@ -1842,138 +1755,9 @@ const LabelPage = ({
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const group = usePaperStore.getState().group
|
||||
if (!group) return
|
||||
|
||||
const targetItems = group
|
||||
.getItems({ data: { id: selectedContext.objectId } })
|
||||
.filter((item) => item.data?.type === "polygon")
|
||||
if (!targetItems.length) return
|
||||
|
||||
let workingShape = createWorkingPolygonShape(targetItems)
|
||||
if (!workingShape || !hasShapeSegments(workingShape)) return
|
||||
|
||||
const otherPolygonPaths: paper.Path[] = []
|
||||
group.children.forEach((item: any) => {
|
||||
if (
|
||||
!item.visible ||
|
||||
!item.data?.id ||
|
||||
item.data.id === selectedContext.objectId ||
|
||||
item.data.type !== "polygon"
|
||||
)
|
||||
return
|
||||
if (item instanceof paper.Path) {
|
||||
if (item.segments?.length) otherPolygonPaths.push(item)
|
||||
} else if (item instanceof paper.CompoundPath) {
|
||||
;(item.children as paper.Path[]).forEach((child) => {
|
||||
if (child.segments?.length) otherPolygonPaths.push(child)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
let changed = false
|
||||
|
||||
for (const eachPath of otherPolygonPaths) {
|
||||
if (!workingShape || !hasShapeSegments(workingShape)) break
|
||||
|
||||
const eachPathClone = eachPath.clone({ insert: false }) as paper.Path
|
||||
const intersectionPath = (workingShape as any).intersect(
|
||||
eachPathClone,
|
||||
{
|
||||
insert: false,
|
||||
}
|
||||
) as paper.Path | paper.CompoundPath
|
||||
const hasIntersection = hasShapeSegments(intersectionPath)
|
||||
intersectionPath?.remove()
|
||||
if (!hasIntersection) {
|
||||
eachPathClone.remove()
|
||||
continue
|
||||
}
|
||||
|
||||
const nextShape: paper.Path | paper.CompoundPath =
|
||||
mode === "subtract"
|
||||
? ((workingShape as any).subtract(eachPathClone, {
|
||||
insert: false,
|
||||
}) as paper.Path | paper.CompoundPath)
|
||||
: ((workingShape as any).unite(eachPathClone, {
|
||||
insert: false,
|
||||
}) as paper.Path | paper.CompoundPath)
|
||||
eachPathClone.remove()
|
||||
workingShape?.remove()
|
||||
workingShape = nextShape
|
||||
changed = true
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
workingShape?.remove()
|
||||
return
|
||||
}
|
||||
if (!workingShape) return
|
||||
|
||||
const raster = usePaperStore.getState().rasterPath
|
||||
if (raster && hasShapeSegments(workingShape)) {
|
||||
const clippedShape = (workingShape as any).intersect(raster, {
|
||||
insert: false,
|
||||
trace: false,
|
||||
}) as paper.Path | paper.CompoundPath
|
||||
workingShape?.remove()
|
||||
workingShape = clippedShape
|
||||
}
|
||||
if (!workingShape) return
|
||||
|
||||
const { polygonPoints, polygonHollowPoints } =
|
||||
collectPolygonPoints(workingShape)
|
||||
workingShape?.remove()
|
||||
|
||||
const nextLabel = safeClone(useLabelStore.getState().label)
|
||||
const imageLabel = nextLabel.get(selectedContext.imageId)
|
||||
if (!imageLabel) return
|
||||
const operationPaths = safeClone(
|
||||
imageLabel.get(selectedContext.operationId) || []
|
||||
)
|
||||
const selectedIndex = operationPaths.findIndex(
|
||||
(item) => item[0] === selectedContext.objectId
|
||||
)
|
||||
if (selectedIndex === -1) return
|
||||
|
||||
const currentTuple = operationPaths[selectedIndex]
|
||||
if (polygonPoints.length) {
|
||||
operationPaths[selectedIndex] = [
|
||||
selectedContext.objectId,
|
||||
polygonPoints,
|
||||
safeClone(currentTuple?.[2] || {}),
|
||||
polygonHollowPoints,
|
||||
]
|
||||
imageLabel.set(selectedContext.operationId, operationPaths)
|
||||
} else {
|
||||
imageLabel.set(
|
||||
selectedContext.operationId,
|
||||
operationPaths.filter((item) => item[0] !== selectedContext.objectId)
|
||||
)
|
||||
removeObjectFromGroupMap(
|
||||
selectedContext.imageId,
|
||||
selectedContext.objectId
|
||||
)
|
||||
}
|
||||
|
||||
useLabelStore.getState().setLabel(nextLabel)
|
||||
useLabelStore.getState().pushStateStack(nextLabel)
|
||||
|
||||
rerenderActiveImageByLabel(
|
||||
selectedContext.imageId,
|
||||
imageLabel,
|
||||
polygonPoints.length ? [selectedContext.objectId] : []
|
||||
)
|
||||
usePaperStore.getState().applySelectedPolygonBooleanOperation(mode)
|
||||
},
|
||||
[
|
||||
collectPolygonPoints,
|
||||
createWorkingPolygonShape,
|
||||
hasShapeSegments,
|
||||
removeObjectFromGroupMap,
|
||||
rerenderActiveImageByLabel,
|
||||
resolveSelectedObjectContext,
|
||||
]
|
||||
[resolveSelectedObjectContext]
|
||||
)
|
||||
|
||||
const applySelectedBrushIntersectUnite = useCallback(() => {
|
||||
@@ -2638,7 +2422,7 @@ const LabelPage = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (!isView) {
|
||||
const delay = 10 * 60000
|
||||
const delay = 5 * 60000
|
||||
// 编辑模式下,修改labelData时启动或更新定时器
|
||||
useTimerStore.getState().startTimer(() => {
|
||||
useTopToolsStore.getState().setIsView(true)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user