Files
geekai/docs/ai3d.md
2025-09-02 18:55:45 +08:00

511 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 开发 3D 图片生成功能
对接 3D 图片生成接口,为当前系统添加 3D 模型生成功能,默认支持腾讯云和 Gitee 的图生 3D API 接口。
## 要求
1. 完成数据库设计,后端 API 设计,前端页面设计。
2. 完成前端功能页面以及后台管理页面,具体设计结构可以参考即梦 AI在对应的模块建立独立的模块 。
3. 页面设计要精美,但是整体风格要跟整站风格一致。
4. 支持前端 3D 模型预览,支持 3D 模型下载。
## 腾讯云图生 3D API 接口文档
1. 提交任务: https://cloud.tencent.com/document/product/1804/120826
2. 查询任务: https://cloud.tencent.com/document/product/1804/120827
3. Golang SDK https://gitee.com/TencentCloud/tencentcloud-sdk-go/blob/master/tencentcloud/ai3d/v20250513/client.go 依赖已经安装到本地了,如果你无法读取远程文件,下面是文件主要内容:
client.go
```go
// Copyright (c) 2017-2025 Tencent. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v20250513
import (
"context"
"errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
)
const APIVersion = "2025-05-13"
type Client struct {
common.Client
}
// Deprecated
func NewClientWithSecretId(secretId, secretKey, region string) (client *Client, err error) {
cpf := profile.NewClientProfile()
client = &Client{}
client.Init(region).WithSecretId(secretId, secretKey).WithProfile(cpf)
return
}
func NewClient(credential common.CredentialIface, region string, clientProfile *profile.ClientProfile) (client *Client, err error) {
client = &Client{}
client.Init(region).
WithCredential(credential).
WithProfile(clientProfile)
return
}
func NewQueryHunyuanTo3DJobRequest() (request *QueryHunyuanTo3DJobRequest) {
request = &QueryHunyuanTo3DJobRequest{
BaseRequest: &tchttp.BaseRequest{},
}
request.Init().WithApiInfo("ai3d", APIVersion, "QueryHunyuanTo3DJob")
return
}
func NewQueryHunyuanTo3DJobResponse() (response *QueryHunyuanTo3DJobResponse) {
response = &QueryHunyuanTo3DJobResponse{
BaseResponse: &tchttp.BaseResponse{},
}
return
}
// QueryHunyuanTo3DJob
// 混元生3D接口基于混元大模型根据输入的文本描述/图片智能生成3D。
//
// 默认提供1个并发代表最多能同时处理1个已提交的任务上一个任务处理完毕后才能开始处理下一个任务。
func (c *Client) QueryHunyuanTo3DJob(request *QueryHunyuanTo3DJobRequest) (response *QueryHunyuanTo3DJobResponse, err error) {
return c.QueryHunyuanTo3DJobWithContext(context.Background(), request)
}
// QueryHunyuanTo3DJob
// 混元生3D接口基于混元大模型根据输入的文本描述/图片智能生成3D。
//
// 默认提供1个并发代表最多能同时处理1个已提交的任务上一个任务处理完毕后才能开始处理下一个任务。
func (c *Client) QueryHunyuanTo3DJobWithContext(ctx context.Context, request *QueryHunyuanTo3DJobRequest) (response *QueryHunyuanTo3DJobResponse, err error) {
if request == nil {
request = NewQueryHunyuanTo3DJobRequest()
}
c.InitBaseRequest(&request.BaseRequest, "ai3d", APIVersion, "QueryHunyuanTo3DJob")
if c.GetCredential() == nil {
return nil, errors.New("QueryHunyuanTo3DJob require credential")
}
request.SetContext(ctx)
response = NewQueryHunyuanTo3DJobResponse()
err = c.Send(request, response)
return
}
func NewSubmitHunyuanTo3DJobRequest() (request *SubmitHunyuanTo3DJobRequest) {
request = &SubmitHunyuanTo3DJobRequest{
BaseRequest: &tchttp.BaseRequest{},
}
request.Init().WithApiInfo("ai3d", APIVersion, "SubmitHunyuanTo3DJob")
return
}
func NewSubmitHunyuanTo3DJobResponse() (response *SubmitHunyuanTo3DJobResponse) {
response = &SubmitHunyuanTo3DJobResponse{
BaseResponse: &tchttp.BaseResponse{},
}
return
}
// SubmitHunyuanTo3DJob
// 混元生3D接口基于混元大模型根据输入的文本描述/图片智能生成3D。
//
// 默认提供1个并发代表最多能同时处理1个已提交的任务上一个任务处理完毕后才能开始处理下一个任务。
func (c *Client) SubmitHunyuanTo3DJob(request *SubmitHunyuanTo3DJobRequest) (response *SubmitHunyuanTo3DJobResponse, err error) {
return c.SubmitHunyuanTo3DJobWithContext(context.Background(), request)
}
// SubmitHunyuanTo3DJob
// 混元生3D接口基于混元大模型根据输入的文本描述/图片智能生成3D。
//
// 默认提供1个并发代表最多能同时处理1个已提交的任务上一个任务处理完毕后才能开始处理下一个任务。
func (c *Client) SubmitHunyuanTo3DJobWithContext(ctx context.Context, request *SubmitHunyuanTo3DJobRequest) (response *SubmitHunyuanTo3DJobResponse, err error) {
if request == nil {
request = NewSubmitHunyuanTo3DJobRequest()
}
c.InitBaseRequest(&request.BaseRequest, "ai3d", APIVersion, "SubmitHunyuanTo3DJob")
if c.GetCredential() == nil {
return nil, errors.New("SubmitHunyuanTo3DJob require credential")
}
request.SetContext(ctx)
response = NewSubmitHunyuanTo3DJobResponse()
err = c.Send(request, response)
return
}
```
model.go
```go
// Copyright (c) 2017-2025 Tencent. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v20250513
import (
tcerr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json"
)
type File3D struct {
// 文件格式
Type *string `json:"Type,omitnil,omitempty" name:"Type"`
// 文件的Url有效期24小时
Url *string `json:"Url,omitnil,omitempty" name:"Url"`
// 预览图片Url
PreviewImageUrl *string `json:"PreviewImageUrl,omitnil,omitempty" name:"PreviewImageUrl"`
}
// Predefined struct for user
type QueryHunyuanTo3DJobRequestParams struct {
// 任务ID。
JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
}
type QueryHunyuanTo3DJobRequest struct {
*tchttp.BaseRequest
// 任务ID。
JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
}
func (r *QueryHunyuanTo3DJobRequest) ToJsonString() string {
b, _ := json.Marshal(r)
return string(b)
}
// FromJsonString It is highly **NOT** recommended to use this function
// because it has no param check, nor strict type check
func (r *QueryHunyuanTo3DJobRequest) FromJsonString(s string) error {
f := make(map[string]interface{})
if err := json.Unmarshal([]byte(s), &f); err != nil {
return err
}
delete(f, "JobId")
if len(f) > 0 {
return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "QueryHunyuanTo3DJobRequest has unknown keys!", "")
}
return json.Unmarshal([]byte(s), &r)
}
// Predefined struct for user
type QueryHunyuanTo3DJobResponseParams struct {
// 任务状态。WAIT等待中RUN执行中FAIL任务失败DONE任务成功
Status *string `json:"Status,omitnil,omitempty" name:"Status"`
// 错误码
ErrorCode *string `json:"ErrorCode,omitnil,omitempty" name:"ErrorCode"`
// 错误信息
ErrorMessage *string `json:"ErrorMessage,omitnil,omitempty" name:"ErrorMessage"`
// 生成的3D文件数组。
ResultFile3Ds []*File3D `json:"ResultFile3Ds,omitnil,omitempty" name:"ResultFile3Ds"`
// 唯一请求 ID由服务端生成每次请求都会返回若请求因其他原因未能抵达服务端则该次请求不会获得 RequestId。定位问题时需要提供该次请求的 RequestId。
RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
}
type QueryHunyuanTo3DJobResponse struct {
*tchttp.BaseResponse
Response *QueryHunyuanTo3DJobResponseParams `json:"Response"`
}
func (r *QueryHunyuanTo3DJobResponse) ToJsonString() string {
b, _ := json.Marshal(r)
return string(b)
}
// FromJsonString It is highly **NOT** recommended to use this function
// because it has no param check, nor strict type check
func (r *QueryHunyuanTo3DJobResponse) FromJsonString(s string) error {
return json.Unmarshal([]byte(s), &r)
}
// Predefined struct for user
type SubmitHunyuanTo3DJobRequestParams struct {
// 文生3D3D内容的描述中文正向提示词。
// 最多支持1024个 utf-8 字符。
// 文生3D, image、image_url和 prompt必填其一且prompt和image/image_url不能同时存在。
Prompt *string `json:"Prompt,omitnil,omitempty" name:"Prompt"`
// 输入图 Base64 数据。
// 大小单边分辨率要求不小于128不大于5000。大小不超过8mbase64编码后会大30%左右建议实际输入图片不超过6m
// 格式jpgpngjpegwebp。
// ImageBase64、ImageUrl和 Prompt必填其一且Prompt和ImageBase64/ImageUrl不能同时存在。
ImageBase64 *string `json:"ImageBase64,omitnil,omitempty" name:"ImageBase64"`
// 输入图Url。
// 大小单边分辨率要求不小于128不大于5000。大小不超过8mbase64编码后会大30%左右建议实际输入图片不超过6m
// 格式jpgpngjpegwebp。
// ImageBase64/ImageUrl和 Prompt必填其一且Prompt和ImageBase64/ImageUrl不能同时存在。
ImageUrl *string `json:"ImageUrl,omitnil,omitempty" name:"ImageUrl"`
// 多视角的模型图片,视角参考值:
// left左视图
// right右视图
// back后视图
//
// 每个视角仅限制一张图片。
// ●图片大小限制编码后大小不可超过8M。
// ●图片分辨率限制单边分辨率小于5000且大于128。
// ●支持图片格式支持jpg或png
MultiViewImages []*ViewImage `json:"MultiViewImages,omitnil,omitempty" name:"MultiViewImages"`
// 生成模型的格式,仅限制生成一种格式。
// 生成模型文件组默认返回obj格式。
// 可选值OBJGLBSTLUSDZFBXMP4。
ResultFormat *string `json:"ResultFormat,omitnil,omitempty" name:"ResultFormat"`
// 是否开启 PBR材质生成默认 false。
EnablePBR *bool `json:"EnablePBR,omitnil,omitempty" name:"EnablePBR"`
}
type SubmitHunyuanTo3DJobRequest struct {
*tchttp.BaseRequest
// 文生3D3D内容的描述中文正向提示词。
// 最多支持1024个 utf-8 字符。
// 文生3D, image、image_url和 prompt必填其一且prompt和image/image_url不能同时存在。
Prompt *string `json:"Prompt,omitnil,omitempty" name:"Prompt"`
// 输入图 Base64 数据。
// 大小单边分辨率要求不小于128不大于5000。大小不超过8mbase64编码后会大30%左右建议实际输入图片不超过6m
// 格式jpgpngjpegwebp。
// ImageBase64、ImageUrl和 Prompt必填其一且Prompt和ImageBase64/ImageUrl不能同时存在。
ImageBase64 *string `json:"ImageBase64,omitnil,omitempty" name:"ImageBase64"`
// 输入图Url。
// 大小单边分辨率要求不小于128不大于5000。大小不超过8mbase64编码后会大30%左右建议实际输入图片不超过6m
// 格式jpgpngjpegwebp。
// ImageBase64/ImageUrl和 Prompt必填其一且Prompt和ImageBase64/ImageUrl不能同时存在。
ImageUrl *string `json:"ImageUrl,omitnil,omitempty" name:"ImageUrl"`
// 多视角的模型图片,视角参考值:
// left左视图
// right右视图
// back后视图
//
// 每个视角仅限制一张图片。
// ●图片大小限制编码后大小不可超过8M。
// ●图片分辨率限制单边分辨率小于5000且大于128。
// ●支持图片格式支持jpg或png
MultiViewImages []*ViewImage `json:"MultiViewImages,omitnil,omitempty" name:"MultiViewImages"`
// 生成模型的格式,仅限制生成一种格式。
// 生成模型文件组默认返回obj格式。
// 可选值OBJGLBSTLUSDZFBXMP4。
ResultFormat *string `json:"ResultFormat,omitnil,omitempty" name:"ResultFormat"`
// 是否开启 PBR材质生成默认 false。
EnablePBR *bool `json:"EnablePBR,omitnil,omitempty" name:"EnablePBR"`
}
func (r *SubmitHunyuanTo3DJobRequest) ToJsonString() string {
b, _ := json.Marshal(r)
return string(b)
}
// FromJsonString It is highly **NOT** recommended to use this function
// because it has no param check, nor strict type check
func (r *SubmitHunyuanTo3DJobRequest) FromJsonString(s string) error {
f := make(map[string]interface{})
if err := json.Unmarshal([]byte(s), &f); err != nil {
return err
}
delete(f, "Prompt")
delete(f, "ImageBase64")
delete(f, "ImageUrl")
delete(f, "MultiViewImages")
delete(f, "ResultFormat")
delete(f, "EnablePBR")
if len(f) > 0 {
return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "SubmitHunyuanTo3DJobRequest has unknown keys!", "")
}
return json.Unmarshal([]byte(s), &r)
}
// Predefined struct for user
type SubmitHunyuanTo3DJobResponseParams struct {
// 任务ID有效期24小时
JobId *string `json:"JobId,omitnil,omitempty" name:"JobId"`
// 唯一请求 ID由服务端生成每次请求都会返回若请求因其他原因未能抵达服务端则该次请求不会获得 RequestId。定位问题时需要提供该次请求的 RequestId。
RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
}
type SubmitHunyuanTo3DJobResponse struct {
*tchttp.BaseResponse
Response *SubmitHunyuanTo3DJobResponseParams `json:"Response"`
}
func (r *SubmitHunyuanTo3DJobResponse) ToJsonString() string {
b, _ := json.Marshal(r)
return string(b)
}
// FromJsonString It is highly **NOT** recommended to use this function
// because it has no param check, nor strict type check
func (r *SubmitHunyuanTo3DJobResponse) FromJsonString(s string) error {
return json.Unmarshal([]byte(s), &r)
}
type ViewImage struct {
// 视角类型。
// 取值back、left、right
ViewType *string `json:"ViewType,omitnil,omitempty" name:"ViewType"`
// 图片Url地址
ViewImageUrl *string `json:"ViewImageUrl,omitnil,omitempty" name:"ViewImageUrl"`
}
```
## Gitee 图生 3D API 接口文档
1. 提交任务: https://ai.gitee.com/docs/openapi/v1#tag/3d-%E7%94%9F%E6%88%90/post/async/image-to-3d
2. 查询任务https://ai.gitee.com/docs/openapi/v1#tag/%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1/get/task/{task_id}/get
首先,你需要认真阅读上述接口文档,然后按照接口文档的示例代码实现腾讯云和 Gitee 的图生 3D API 接口,并且将接口集成到现有的系统中。
📋 功能概述
为现有的GeekAI-Plus系统添加3D图片生成功能集成腾讯云和Gitee的图生3D API接口包含完整的前后端功能和管理界面。
🗄️ 数据库设计
新增数据表geekai_3d_jobs
- id (uint): 主键
- type (string): API类型 (tencent/gitee)
- user_id (uint): 用户ID
- power (int): 消耗算力
- task_id (string): 第三方任务ID
- img_url (string): 生成的3D模型文件地址
- model (string): 使用的3D模型类型
- status (string): 任务状态
- err_msg (string): 错误信息
- params (JSON): 任务参数(包含输入图片、提示词等所有参数)
- created_at (int64): 创建时间
🔧 后端API实现
路由结构:/api/3d/*
- POST /api/3d/generate - 创建3D生成任务
- GET /api/3d/jobs - 获取任务列表
- GET /api/3d/job/{id} - 获取任务详情
- GET /api/3d/download/{id} - 下载3D模型
- DELETE /api/3d/job/{id} - 删除任务
核心服务:
- service/3d/tencent_client.go - 腾讯云3D API客户端
- service/3d/gitee_client.go - Gitee 3D API客户端
- service/3d/service.go - 3D生成服务统一接口
- handler/3d_handler.go - HTTP处理器
- store/vo/3d_job.go - 数据模型
🎨 前端界面设计
用户端页面:/3d - 3D生成主页面
- 参考JiMeng.vue的设计风格和布局
- 使用CustomTab组件分离平台参数
- Tab 1: "魔力方舟" (Gitee平台参数)
- Tab 2: "腾讯混元" (腾讯云平台参数)
- 每个Tab内包含
- 图片上传区域
- 模型选择下拉框
- 算力消耗实时显示
- 平台特定的参数配置
- 生成按钮
- 任务列表和状态显示
- 集成3D模型预览器 (three.js)
- 模型下载功能
移动端适配:
- mobile/3dCreate.vue - 移动端3D生成页面
- 保持Tab切换功能
- 响应式设计,触控优化
🛠️ 管理后台
管理功能:
- admin/3d/3dJobs.vue - 任务管理列表
- admin/3d/3dSetting.vue - API配置页面
- 模型配置管理:
- 分平台配置API秘钥和模型列表
- 设置每个模型的算力消耗值
- API密钥和端点配置
🔌 API集成方案
腾讯云集成:
- 使用官方Golang SDK
- 支持异步任务提交和状态查询
Gitee集成
- HTTP客户端实现
- 标准化响应处理
🎯 核心功能特性
- 平台切换通过CustomTab在魔力方舟和腾讯混元间切换
- 模型选择每个平台支持不同的3D模型
- 动态算力:切换模型时实时更新算力消耗显示
- 参数隔离:不同平台的参数配置完全分离
- 3D预览集成Three.js实现模型预览
- 统一体验保持与JiMeng.vue相似的交互风格
📱 用户体验
- JiMeng.vue风格的简洁界面
- Tab切换流畅的平台选择
- 模型选择时算力消耗实时更新
- 支持拖拽上传图片
- 实时任务状态显示
- 3D模型交互式预览
这个设计将创建一个与现有JiMeng功能风格一致的3D生成模块通过Tab分离实现平台参数的清晰管理。
整个实现严格按照现有系统的代码规范和架构模式,与 JiMeng 等模块保持一致的用户体验!